2015-03-13 21:24:58 +05:30
/******************************************************************************
*
* 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
*/
/*****************************************************************************/
/* */
/* File Name : main.c */
/* */
/* Description : Contains an application that demonstrates use of H264*/
/* decoder API */
/* */
/* List of Functions : */
/* */
/* Issues / Problems : None */
/* */
/* Revision History : */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 Harish Initial Version */
/*****************************************************************************/
/*****************************************************************************/
/* File Includes */
/*****************************************************************************/
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# ifdef X86_MINGW
# include <signal.h>
# endif
# ifndef IOS
# include <malloc.h>
# endif
# ifdef IOS_DISPLAY
# include "cast_types.h"
# else
# include "ih264_typedefs.h"
# endif
# include "iv.h"
# include "ivd.h"
# include "ih264d.h"
# include "ithread.h"
# ifdef WINDOWS_TIMER
# include <windows.h>
# else
# include <sys/time.h>
# endif
2015-08-04 09:55:15 +05:30
//#define ADAPTIVE_TEST
2015-09-02 09:01:40 +05:30
# define ADAPTIVE_MAX_WD 4096
# define ADAPTIVE_MAX_HT 2160
2015-06-03 07:26:32 -07:00
2015-03-13 21:24:58 +05:30
# define ALIGN8(x) ((((x) + 7) >> 3) << 3)
# define NUM_DISPLAY_BUFFERS 4
# define DEFAULT_FPS 30
# define ENABLE_DEGRADE 0
# define MAX_DISP_BUFFERS 64
# define EXTRA_DISP_BUFFERS 8
# define STRLENGTH 1000
//#define TEST_FLUSH
# define FLUSH_FRM_CNT 100
//#define APP_EXTRA_BUFS 1
# ifdef IOS
# define PATHLENMAX 500
char filename_with_path [ PATHLENMAX ] ;
# endif
# ifdef PROFILE_ENABLE
# ifdef WINDOWS_TIMER
typedef LARGE_INTEGER TIMER ;
# else
//#ifdef GCC_TIMER
typedef struct timeval TIMER ;
//#endif
# endif
# else
typedef WORD32 TIMER ;
# endif
# ifdef PROFILE_ENABLE
# ifdef WINDOWS_TIMER
# define GETTIME(timer) QueryPerformanceCounter(timer);
# else
//#ifdef GCC_TIMER
# define GETTIME(timer) gettimeofday(timer,NULL);
//#endif
# endif
# ifdef WINDOWS_TIMER
# define ELAPSEDTIME(s_start_timer,s_end_timer, s_elapsed_time, frequency) \
{ \
TIMER s_temp_time ; \
s_temp_time . LowPart = s_end_timer . LowPart - s_start_timer . LowPart ; \
s_elapsed_time = ( UWORD32 ) ( ( ( DOUBLE ) s_temp_time . LowPart / ( DOUBLE ) frequency . LowPart ) * 1000000 ) ; \
}
# else
//#ifdef GCC_TIMER
# define ELAPSEDTIME(s_start_timer,s_end_timer, s_elapsed_time, frequency) \
s_elapsed_time = ( ( s_end_timer . tv_sec - s_start_timer . tv_sec ) * 1000000 ) + ( s_end_timer . tv_usec - s_start_timer . tv_usec ) ;
//#endif
# endif
# else
# define GETTIME(timer)
# define ELAPSEDTIME(s_start_timer,s_end_timer, s_elapsed_time, frequency)
# endif
/* Function declarations */
# ifndef MD5_DISABLE
void calc_md5_cksum ( UWORD8 * pu1_inbuf , UWORD32 u4_stride , UWORD32 u4_width , UWORD32 u4_height , UWORD8 * pu1_cksum_p ) ;
# else
# define calc_md5_cksum(a, b, c, d, e)
# endif
# ifdef SDL_DISPLAY
void * sdl_disp_init ( UWORD32 , UWORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 * , WORD32 * ) ;
void sdl_alloc_disp_buffers ( void * ) ;
void sdl_display ( void * , WORD32 ) ;
void sdl_set_disp_buffers ( void * , WORD32 , UWORD8 * * , UWORD8 * * , UWORD8 * * ) ;
void sdl_disp_deinit ( void * ) ;
void sdl_disp_usleep ( UWORD32 ) ;
IV_COLOR_FORMAT_T sdl_get_color_fmt ( void ) ;
UWORD32 sdl_get_stride ( void ) ;
# endif
# ifdef INTEL_CE5300
void * gdl_disp_init ( UWORD32 , UWORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 * , WORD32 * ) ;
void gdl_alloc_disp_buffers ( void * ) ;
void gdl_display ( void * , WORD32 ) ;
void gdl_set_disp_buffers ( void * , WORD32 , UWORD8 * * , UWORD8 * * , UWORD8 * * ) ;
void gdl_disp_deinit ( void * ) ;
void gdl_disp_usleep ( UWORD32 ) ;
IV_COLOR_FORMAT_T gdl_get_color_fmt ( void ) ;
UWORD32 gdl_get_stride ( void ) ;
# endif
# ifdef FBDEV_DISPLAY
void * fbd_disp_init ( UWORD32 , UWORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 * , WORD32 * ) ;
void fbd_alloc_disp_buffers ( void * ) ;
void fbd_display ( void * , WORD32 ) ;
void fbd_set_disp_buffers ( void * , WORD32 , UWORD8 * * , UWORD8 * * , UWORD8 * * ) ;
void fbd_disp_deinit ( void * ) ;
void fbd_disp_usleep ( UWORD32 ) ;
IV_COLOR_FORMAT_T fbd_get_color_fmt ( void ) ;
UWORD32 fbd_get_stride ( void ) ;
# endif
# ifdef IOS_DISPLAY
void * ios_disp_init ( UWORD32 , UWORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 * , WORD32 * ) ;
void ios_alloc_disp_buffers ( void * ) ;
void ios_display ( void * , WORD32 ) ;
void ios_set_disp_buffers ( void * , WORD32 , UWORD8 * * , UWORD8 * * , UWORD8 * * ) ;
void ios_disp_deinit ( void * ) ;
void ios_disp_usleep ( UWORD32 ) ;
IV_COLOR_FORMAT_T ios_get_color_fmt ( void ) ;
UWORD32 ios_get_stride ( void ) ;
# endif
typedef struct
{
UWORD32 u4_piclen_flag ;
UWORD32 u4_file_save_flag ;
UWORD32 u4_chksum_save_flag ;
UWORD32 u4_max_frm_ts ;
IV_COLOR_FORMAT_T e_output_chroma_format ;
IVD_ARCH_T e_arch ;
IVD_SOC_T e_soc ;
UWORD32 dump_q_rd_idx ;
UWORD32 dump_q_wr_idx ;
WORD32 disp_q_wr_idx ;
WORD32 disp_q_rd_idx ;
void * cocodec_obj ;
UWORD32 u4_share_disp_buf ;
UWORD32 num_disp_buf ;
UWORD32 b_pic_present ;
UWORD32 u4_disable_dblk_level ;
WORD32 i4_degrade_type ;
WORD32 i4_degrade_pics ;
UWORD32 u4_num_cores ;
UWORD32 disp_delay ;
WORD32 trace_enable ;
CHAR ac_trace_fname [ STRLENGTH ] ;
CHAR ac_piclen_fname [ STRLENGTH ] ;
CHAR ac_ip_fname [ STRLENGTH ] ;
CHAR ac_op_fname [ STRLENGTH ] ;
CHAR ac_op_chksum_fname [ STRLENGTH ] ;
ivd_out_bufdesc_t s_disp_buffers [ MAX_DISP_BUFFERS ] ;
iv_yuv_buf_t s_disp_frm_queue [ MAX_DISP_BUFFERS ] ;
UWORD32 s_disp_frm_id_queue [ MAX_DISP_BUFFERS ] ;
UWORD32 loopback ;
UWORD32 display ;
UWORD32 full_screen ;
UWORD32 fps ;
UWORD32 u4_strd ;
/* For signalling to display thread */
UWORD32 u4_pic_wd ;
UWORD32 u4_pic_ht ;
/* For IOS diplay */
WORD32 i4_screen_wd ;
WORD32 i4_screen_ht ;
//UWORD32 u4_output_present;
WORD32 quit ;
WORD32 paused ;
void * pv_disp_ctx ;
void * display_thread_handle ;
WORD32 display_thread_created ;
volatile WORD32 display_init_done ;
volatile WORD32 display_deinit_flag ;
void * ( * disp_init ) ( UWORD32 , UWORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 , WORD32 * , WORD32 * ) ;
void ( * alloc_disp_buffers ) ( void * ) ;
void ( * display_buffer ) ( void * , WORD32 ) ;
void ( * set_disp_buffers ) ( void * , WORD32 , UWORD8 * * , UWORD8 * * , UWORD8 * * ) ;
void ( * disp_deinit ) ( void * ) ;
void ( * disp_usleep ) ( UWORD32 ) ;
IV_COLOR_FORMAT_T ( * get_color_fmt ) ( void ) ;
UWORD32 ( * get_stride ) ( void ) ;
} vid_dec_ctx_t ;
typedef enum
{
INVALID ,
HELP ,
VERSION ,
INPUT_FILE ,
OUTPUT ,
CHKSUM ,
SAVE_OUTPUT ,
SAVE_CHKSUM ,
CHROMA_FORMAT ,
NUM_FRAMES ,
NUM_CORES ,
DISABLE_DEBLOCK_LEVEL ,
SHARE_DISPLAY_BUF ,
LOOPBACK ,
DISPLAY ,
FULLSCREEN ,
FPS ,
TRACE ,
CONFIG ,
DEGRADE_TYPE ,
DEGRADE_PICS ,
ARCH ,
SOC ,
PICLEN ,
PICLEN_FILE ,
} ARGUMENT_T ;
typedef struct
{
CHAR argument_shortname [ 4 ] ;
CHAR argument_name [ 128 ] ;
ARGUMENT_T argument ;
CHAR description [ 512 ] ;
} argument_t ;
static const argument_t argument_mapping [ ] =
{
{ " -h " , " --help " , HELP ,
" Print this help \n " } ,
{ " -c " , " --config " , CONFIG ,
" config file (Default: test.cfg) \n " } ,
{ " -v " , " --version " , VERSION ,
" Version information \n " } ,
{ " -i " , " --input " , INPUT_FILE ,
" Input file \n " } ,
{ " -o " , " --output " , OUTPUT ,
" Output file \n " } ,
{ " -- " , " --piclen " , PICLEN ,
" Flag to signal if the decoder has to use a file containing number of bytes in each picture to be fed in each call \n " } ,
{ " -- " , " --piclen_file " , PICLEN_FILE ,
" File containing number of bytes in each picture - each line containing one i4_size \n " } ,
{ " -- " , " --chksum " , CHKSUM ,
" Output MD5 Checksum file \n " } ,
{ " -s " , " --save_output " , SAVE_OUTPUT ,
" Save Output file \n " } ,
{ " -- " , " --save_chksum " , SAVE_CHKSUM ,
" Save Check sum file \n " } ,
{ " -- " , " --chroma_format " , CHROMA_FORMAT ,
" Output Chroma format Supported values YUV_420P, YUV_422ILE, RGB_565, YUV_420SP_UV, YUV_420SP_VU \n " } ,
{ " -n " , " --num_frames " , NUM_FRAMES ,
" Number of frames to be decoded \n " } ,
{ " -- " , " --num_cores " , NUM_CORES ,
" Number of cores to be used \n " } ,
{ " -- " , " --share_display_buf " , SHARE_DISPLAY_BUF ,
" Enable shared display buffer mode \n " } ,
{ " -- " , " --disable_deblock_level " , DISABLE_DEBLOCK_LEVEL ,
" Disable deblocking level : 0 to 4 - 0 Enable deblocking 4 Disable deblocking completely \n " } ,
{ " -- " , " --loopback " , LOOPBACK ,
" Enable playback in a loop \n " } ,
{ " -- " , " --display " , DISPLAY ,
" Enable display (uses SDL) \n " } ,
{ " -- " , " --fullscreen " , FULLSCREEN ,
" Enable full screen (Only for GDL and SDL) \n " } ,
{ " -- " , " --fps " , FPS ,
" FPS to be used for display \n " } ,
{ " -i " , " --trace " , TRACE ,
" Trace file \n " } ,
{ " -- " , " --degrade_type " , DEGRADE_TYPE ,
" Degrade type : 0: No degrade 0th bit set : Disable SAO 1st bit set : Disable deblocking 2nd bit set : Faster inter prediction filters 3rd bit set : Fastest inter prediction filters \n " } ,
{ " -- " , " --degrade_pics " , DEGRADE_PICS ,
" Degrade pics : 0 : No degrade 1 : Only on non-reference frames 2 : Do not degrade every 4th or key frames 3 : All non-key frames 4 : All frames " } ,
{ " -- " , " --arch " , ARCH ,
" Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR,ARMV8_GENERIC, X86_GENERIC, X86_SSSE3, X86_SSE4 \n " } ,
{ " -- " , " --soc " , SOC ,
" Set SOC. Supported values GENERIC, HISI_37X \n " } ,
} ;
# define PEAK_WINDOW_SIZE 8
# define DEFAULT_SHARE_DISPLAY_BUF 0
# define STRIDE 0
# define DEFAULT_NUM_CORES 1
# define DUMP_SINGLE_BUF 0
# define IV_ISFATALERROR(x) (((x) >> IVD_FATALERROR) & 0x1)
# define ivd_api_function ih264d_api_function
# ifdef IOS
char filename_trace [ PATHLENMAX ] ;
# endif
# if ANDROID_NDK
/*****************************************************************************/
/* */
/* Function Name : raise */
/* */
/* Description : Needed as a workaround when the application is built in */
/* Android NDK. This is an exception to be called for divide*/
/* by zero error */
/* */
/* Inputs : a */
/* Globals : */
/* Processing : None */
/* */
/* Outputs : */
/* Returns : */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
int raise ( int a )
{
printf ( " Divide by zero \n " ) ;
return 0 ;
}
# endif
# ifdef _WIN32
/*****************************************************************************/
/* Function to print library calls */
/*****************************************************************************/
/*****************************************************************************/
/* */
/* Function Name : memalign */
/* */
/* Description : Returns malloc data. Ideally should return aligned memory*/
/* support alignment will be added later */
/* */
/* Inputs : alignment */
/* i4_size */
/* Globals : */
/* Processing : */
/* */
/* Outputs : */
/* Returns : */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
2015-08-04 09:55:15 +05:30
void * ih264a_aligned_malloc ( void * pv_ctxt , WORD32 alignment , WORD32 i4_size )
2015-03-13 21:24:58 +05:30
{
2015-08-04 09:55:15 +05:30
( void ) pv_ctxt ;
2015-03-13 21:24:58 +05:30
return ( void * ) _aligned_malloc ( i4_size , alignment ) ;
}
2015-08-04 09:55:15 +05:30
void ih264a_aligned_free ( void * pv_ctxt , void * pv_buf )
2015-03-13 21:24:58 +05:30
{
2015-08-04 09:55:15 +05:30
( void ) pv_ctxt ;
2015-03-13 21:24:58 +05:30
_aligned_free ( pv_buf ) ;
return ;
}
# endif
# if IOS
2015-08-04 09:55:15 +05:30
void * ih264a_aligned_malloc ( void * pv_ctxt , WORD32 alignment , WORD32 i4_size )
2015-03-13 21:24:58 +05:30
{
2015-08-04 09:55:15 +05:30
( void ) pv_ctxt ;
2015-03-13 21:24:58 +05:30
return malloc ( i4_size ) ;
}
2015-08-04 09:55:15 +05:30
void ih264a_aligned_free ( void * pv_ctxt , void * pv_buf )
2015-03-13 21:24:58 +05:30
{
2015-08-04 09:55:15 +05:30
( void ) pv_ctxt ;
2015-03-13 21:24:58 +05:30
free ( pv_buf ) ;
return ;
}
# endif
# if (!defined(IOS)) && (!defined(_WIN32))
2015-08-04 09:55:15 +05:30
void * ih264a_aligned_malloc ( void * pv_ctxt , WORD32 alignment , WORD32 i4_size )
2015-03-13 21:24:58 +05:30
{
2015-08-04 09:55:15 +05:30
( void ) pv_ctxt ;
2015-03-13 21:24:58 +05:30
return memalign ( alignment , i4_size ) ;
}
2015-08-04 09:55:15 +05:30
void ih264a_aligned_free ( void * pv_ctxt , void * pv_buf )
2015-03-13 21:24:58 +05:30
{
2015-08-04 09:55:15 +05:30
( void ) pv_ctxt ;
2015-03-13 21:24:58 +05:30
free ( pv_buf ) ;
return ;
}
# endif
/*****************************************************************************/
/* */
/* Function Name : set_degrade */
/* */
/* Description : Control call to set degrade level */
/* */
/* */
/* Inputs : codec_obj - Codec Handle */
/* type - degrade level value between 0 to 4 */
/* 0 : No degrade */
/* 1st bit : Disable SAO */
/* 2nd bit : Disable Deblock */
/* 3rd bit : Faster MC for non-ref */
/* 4th bit : Fastest MC for non-ref */
/* pics - Pictures that are are degraded */
/* 0 : No degrade */
/* 1 : Non-ref pictures */
/* 2 : Pictures at given interval are not degraded */
/* 3 : All non-key pictures */
/* 4 : All pictures */
/* Globals : */
/* Processing : Calls degrade control to the codec */
/* */
/* Outputs : */
/* Returns : Control call return i4_status */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
IV_API_CALL_STATUS_T set_degrade ( void * codec_obj , UWORD32 type , WORD32 pics )
{
ih264d_ctl_degrade_ip_t s_ctl_ip ;
ih264d_ctl_degrade_op_t s_ctl_op ;
void * pv_api_ip , * pv_api_op ;
IV_API_CALL_STATUS_T e_dec_status ;
s_ctl_ip . u4_size = sizeof ( ih264d_ctl_degrade_ip_t ) ;
s_ctl_ip . i4_degrade_type = type ;
s_ctl_ip . i4_nondegrade_interval = 4 ;
s_ctl_ip . i4_degrade_pics = pics ;
s_ctl_op . u4_size = sizeof ( ih264d_ctl_degrade_op_t ) ;
pv_api_ip = ( void * ) & s_ctl_ip ;
pv_api_op = ( void * ) & s_ctl_op ;
s_ctl_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_ip . e_sub_cmd = ( IVD_CONTROL_API_COMMAND_TYPE_T ) IH264D_CMD_CTL_DEGRADE ;
e_dec_status = ivd_api_function ( ( iv_obj_t * ) codec_obj , pv_api_ip , pv_api_op ) ;
if ( IV_SUCCESS ! = e_dec_status )
{
printf ( " Error in setting degrade level \n " ) ;
}
return ( e_dec_status ) ;
}
/*****************************************************************************/
/* */
/* Function Name : enable_skipb_frames */
/* */
/* Description : Control call to enable skipping of b frames */
/* */
/* */
/* Inputs : codec_obj : Codec handle */
/* Globals : */
/* Processing : Calls enable skip B frames control */
/* */
/* Outputs : */
/* Returns : Control call return i4_status */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
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 ;
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 ;
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 ) ;
e_dec_status = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( IV_SUCCESS ! = e_dec_status )
{
printf ( " Error in Enable SkipB frames \n " ) ;
}
return e_dec_status ;
}
/*****************************************************************************/
/* */
/* Function Name : disable_skipb_frames */
/* */
/* Description : Control call to disable skipping of b frames */
/* */
/* */
/* Inputs : codec_obj : Codec handle */
/* Globals : */
/* Processing : Calls disable B frame skip control */
/* */
/* Outputs : */
/* Returns : Control call return i4_status */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
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 ;
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 ;
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 ) ;
e_dec_status = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( IV_SUCCESS ! = e_dec_status )
{
printf ( " Error in Disable SkipB frames \n " ) ;
}
return e_dec_status ;
}
/*****************************************************************************/
/* */
/* Function Name : enable_skippb_frames */
/* */
/* Description : Control call to enable skipping of P & B frames */
/* */
/* */
/* Inputs : codec_obj : Codec handle */
/* Globals : */
/* Processing : Calls enable skip P and B frames control */
/* */
/* Outputs : */
/* Returns : Control call return i4_status */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
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 ;
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 ;
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 ) ;
e_dec_status = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( IV_SUCCESS ! = e_dec_status )
{
printf ( " Error in Enable SkipPB frames \n " ) ;
}
return e_dec_status ;
}
/*****************************************************************************/
/* */
/* Function Name : disable_skippb_frames */
/* */
/* Description : Control call to disable skipping of P and B frames */
/* */
/* */
/* Inputs : codec_obj : Codec handle */
/* Globals : */
/* Processing : Calls disable P and B frame skip control */
/* */
/* Outputs : */
/* Returns : Control call return i4_status */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
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 ;
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 ;
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 ) ;
e_dec_status = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( IV_SUCCESS ! = e_dec_status )
{
printf ( " Error in Disable SkipPB frames \n " ) ;
}
return e_dec_status ;
}
/*****************************************************************************/
/* */
/* Function Name : release_disp_frame */
/* */
/* Description : Calls release display control - Used to signal to the */
/* decoder that this particular buffer has been displayed */
/* and that the codec is now free to write to this buffer */
/* */
/* */
/* Inputs : codec_obj : Codec Handle */
/* buf_id : Buffer Id of the buffer to be released */
/* This id would have been returned earlier by */
/* the codec */
/* Globals : */
/* Processing : Calls Release Display call */
/* */
/* Outputs : */
/* Returns : Status of release display call */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
IV_API_CALL_STATUS_T release_disp_frame ( void * codec_obj , UWORD32 buf_id )
{
ivd_rel_display_frame_ip_t s_video_rel_disp_ip ;
ivd_rel_display_frame_op_t s_video_rel_disp_op ;
IV_API_CALL_STATUS_T e_dec_status ;
s_video_rel_disp_ip . e_cmd = IVD_CMD_REL_DISPLAY_FRAME ;
s_video_rel_disp_ip . u4_size = sizeof ( ivd_rel_display_frame_ip_t ) ;
s_video_rel_disp_op . u4_size = sizeof ( ivd_rel_display_frame_op_t ) ;
s_video_rel_disp_ip . u4_disp_buf_id = buf_id ;
e_dec_status = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_video_rel_disp_ip ,
( void * ) & s_video_rel_disp_op ) ;
if ( IV_SUCCESS ! = e_dec_status )
{
printf ( " Error in Release Disp frame \n " ) ;
}
return ( e_dec_status ) ;
}
/*****************************************************************************/
/* */
/* Function Name : get_version */
/* */
/* Description : Control call to get codec version */
/* */
/* */
/* Inputs : codec_obj : Codec handle */
/* Globals : */
/* Processing : Calls enable skip B frames control */
/* */
/* Outputs : */
/* Returns : Control call return i4_status */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
IV_API_CALL_STATUS_T get_version ( void * codec_obj )
{
ivd_ctl_getversioninfo_ip_t ps_ctl_ip ;
ivd_ctl_getversioninfo_op_t ps_ctl_op ;
UWORD8 au1_buf [ 512 ] ;
IV_API_CALL_STATUS_T i4_status ;
ps_ctl_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
ps_ctl_ip . e_sub_cmd = IVD_CMD_CTL_GETVERSION ;
ps_ctl_ip . u4_size = sizeof ( ivd_ctl_getversioninfo_ip_t ) ;
ps_ctl_op . u4_size = sizeof ( ivd_ctl_getversioninfo_op_t ) ;
ps_ctl_ip . pv_version_buffer = au1_buf ;
ps_ctl_ip . u4_version_buffer_size = sizeof ( au1_buf ) ;
i4_status = ivd_api_function ( ( iv_obj_t * ) codec_obj ,
( void * ) & ( ps_ctl_ip ) ,
( void * ) & ( ps_ctl_op ) ) ;
if ( i4_status ! = IV_SUCCESS )
{
printf ( " Error in Getting Version number e_dec_status = %d u4_error_code = %x \n " ,
i4_status , ps_ctl_op . u4_error_code ) ;
}
else
{
printf ( " Ittiam Decoder Version number: %s \n " ,
( char * ) ps_ctl_ip . pv_version_buffer ) ;
}
return i4_status ;
}
/*****************************************************************************/
/* */
/* Function Name : codec_exit */
/* */
/* Description : handles unrecoverable errors */
/* Inputs : Error message */
/* Globals : None */
/* Processing : Prints error message to console and exits. */
/* Outputs : Error mesage to the console */
/* Returns : None */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 07 06 2006 Sankar Creation */
/* */
/*****************************************************************************/
void codec_exit ( CHAR * pc_err_message )
{
printf ( " %s \n " , pc_err_message ) ;
exit ( - 1 ) ;
}
/*****************************************************************************/
/* */
/* Function Name : dump_output */
/* */
/* Description : Used to dump output YUV */
/* Inputs : App context, disp output desc, File pointer */
/* Globals : None */
/* Processing : Dumps to a file */
/* Returns : None */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 07 06 2006 Sankar Creation */
/* */
/*****************************************************************************/
void dump_output ( vid_dec_ctx_t * ps_app_ctx ,
iv_yuv_buf_t * ps_disp_frm_buf ,
UWORD32 u4_disp_frm_id ,
FILE * ps_op_file ,
FILE * ps_op_chksum_file ,
WORD32 i4_op_frm_ts ,
UWORD32 file_save ,
UWORD32 chksum_save )
{
UWORD32 i ;
iv_yuv_buf_t s_dump_disp_frm_buf ;
UWORD32 u4_disp_id ;
memset ( & s_dump_disp_frm_buf , 0 , sizeof ( iv_yuv_buf_t ) ) ;
if ( ps_app_ctx - > u4_share_disp_buf )
{
if ( ps_app_ctx - > dump_q_wr_idx = = MAX_DISP_BUFFERS )
ps_app_ctx - > dump_q_wr_idx = 0 ;
if ( ps_app_ctx - > dump_q_rd_idx = = MAX_DISP_BUFFERS )
ps_app_ctx - > dump_q_rd_idx = 0 ;
ps_app_ctx - > s_disp_frm_queue [ ps_app_ctx - > dump_q_wr_idx ] =
* ps_disp_frm_buf ;
ps_app_ctx - > s_disp_frm_id_queue [ ps_app_ctx - > dump_q_wr_idx ] =
u4_disp_frm_id ;
ps_app_ctx - > dump_q_wr_idx + + ;
if ( ( WORD32 ) i4_op_frm_ts > = ( WORD32 ) ( ps_app_ctx - > disp_delay - 1 ) )
{
s_dump_disp_frm_buf =
ps_app_ctx - > s_disp_frm_queue [ ps_app_ctx - > dump_q_rd_idx ] ;
u4_disp_id =
ps_app_ctx - > s_disp_frm_id_queue [ ps_app_ctx - > dump_q_rd_idx ] ;
ps_app_ctx - > dump_q_rd_idx + + ;
}
else
{
return ;
}
}
else
{
s_dump_disp_frm_buf = * ps_disp_frm_buf ;
u4_disp_id = u4_disp_frm_id ;
}
release_disp_frame ( ps_app_ctx - > cocodec_obj , u4_disp_id ) ;
if ( 0 = = file_save & & 0 = = chksum_save )
return ;
if ( NULL = = s_dump_disp_frm_buf . pv_y_buf )
return ;
if ( ps_app_ctx - > e_output_chroma_format = = IV_YUV_420P )
{
# if DUMP_SINGLE_BUF
{
UWORD8 * buf = s_dump_disp_frm_buf . pv_y_buf - 80 - ( s_dump_disp_frm_buf . u4_y_strd * 80 ) ;
UWORD32 i4_size = s_dump_disp_frm_buf . u4_y_strd * ( ( s_dump_disp_frm_buf . u4_y_ht + 160 ) + ( s_dump_disp_frm_buf . u4_u_ht + 80 ) ) ;
fwrite ( buf , 1 , i4_size , ps_op_file ) ;
}
# else
if ( 0 ! = file_save )
{
UWORD8 * buf ;
2015-06-03 07:26:32 -07:00
2015-03-13 21:24:58 +05:30
buf = ( UWORD8 * ) s_dump_disp_frm_buf . pv_y_buf ;
for ( i = 0 ; i < s_dump_disp_frm_buf . u4_y_ht ; i + + )
{
fwrite ( buf , 1 , s_dump_disp_frm_buf . u4_y_wd , ps_op_file ) ;
buf + = s_dump_disp_frm_buf . u4_y_strd ;
}
buf = ( UWORD8 * ) s_dump_disp_frm_buf . pv_u_buf ;
for ( i = 0 ; i < s_dump_disp_frm_buf . u4_u_ht ; i + + )
{
fwrite ( buf , 1 , s_dump_disp_frm_buf . u4_u_wd , ps_op_file ) ;
buf + = s_dump_disp_frm_buf . u4_u_strd ;
}
buf = ( UWORD8 * ) s_dump_disp_frm_buf . pv_v_buf ;
for ( i = 0 ; i < s_dump_disp_frm_buf . u4_v_ht ; i + + )
{
fwrite ( buf , 1 , s_dump_disp_frm_buf . u4_v_wd , ps_op_file ) ;
buf + = s_dump_disp_frm_buf . u4_v_strd ;
}
}
if ( 0 ! = chksum_save )
{
UWORD8 au1_y_chksum [ 16 ] ;
UWORD8 au1_u_chksum [ 16 ] ;
UWORD8 au1_v_chksum [ 16 ] ;
calc_md5_cksum ( ( UWORD8 * ) s_dump_disp_frm_buf . pv_y_buf ,
s_dump_disp_frm_buf . u4_y_strd ,
s_dump_disp_frm_buf . u4_y_wd ,
s_dump_disp_frm_buf . u4_y_ht ,
au1_y_chksum ) ;
calc_md5_cksum ( ( UWORD8 * ) s_dump_disp_frm_buf . pv_u_buf ,
s_dump_disp_frm_buf . u4_u_strd ,
s_dump_disp_frm_buf . u4_u_wd ,
s_dump_disp_frm_buf . u4_u_ht ,
au1_u_chksum ) ;
calc_md5_cksum ( ( UWORD8 * ) s_dump_disp_frm_buf . pv_v_buf ,
s_dump_disp_frm_buf . u4_v_strd ,
s_dump_disp_frm_buf . u4_v_wd ,
s_dump_disp_frm_buf . u4_v_ht ,
au1_v_chksum ) ;
fwrite ( au1_y_chksum , sizeof ( UWORD8 ) , 16 , ps_op_chksum_file ) ;
fwrite ( au1_u_chksum , sizeof ( UWORD8 ) , 16 , ps_op_chksum_file ) ;
fwrite ( au1_v_chksum , sizeof ( UWORD8 ) , 16 , ps_op_chksum_file ) ;
}
# endif
}
else if ( ( ps_app_ctx - > e_output_chroma_format = = IV_YUV_420SP_UV )
| | ( ps_app_ctx - > e_output_chroma_format = = IV_YUV_420SP_VU ) )
{
# if DUMP_SINGLE_BUF
{
UWORD8 * buf = s_dump_disp_frm_buf . pv_y_buf - 24 - ( s_dump_disp_frm_buf . u4_y_strd * 40 ) ;
UWORD32 i4_size = s_dump_disp_frm_buf . u4_y_strd * ( ( s_dump_disp_frm_buf . u4_y_ht + 80 ) + ( s_dump_disp_frm_buf . u4_u_ht + 40 ) ) ;
fwrite ( buf , 1 , i4_size , ps_op_file ) ;
}
# else
{
UWORD8 * buf ;
buf = ( UWORD8 * ) s_dump_disp_frm_buf . pv_y_buf ;
for ( i = 0 ; i < s_dump_disp_frm_buf . u4_y_ht ; i + + )
{
fwrite ( buf , 1 , s_dump_disp_frm_buf . u4_y_wd , ps_op_file ) ;
buf + = s_dump_disp_frm_buf . u4_y_strd ;
}
buf = ( UWORD8 * ) s_dump_disp_frm_buf . pv_u_buf ;
for ( i = 0 ; i < s_dump_disp_frm_buf . u4_u_ht ; i + + )
{
fwrite ( buf , 1 , s_dump_disp_frm_buf . u4_u_wd , ps_op_file ) ;
buf + = s_dump_disp_frm_buf . u4_u_strd ;
}
}
# endif
}
else if ( ps_app_ctx - > e_output_chroma_format = = IV_RGBA_8888 )
{
UWORD8 * buf ;
buf = ( UWORD8 * ) s_dump_disp_frm_buf . pv_y_buf ;
for ( i = 0 ; i < s_dump_disp_frm_buf . u4_y_ht ; i + + )
{
fwrite ( buf , 1 , s_dump_disp_frm_buf . u4_y_wd * 4 , ps_op_file ) ;
buf + = s_dump_disp_frm_buf . u4_y_strd * 4 ;
}
}
else
{
UWORD8 * buf ;
buf = ( UWORD8 * ) s_dump_disp_frm_buf . pv_y_buf ;
for ( i = 0 ; i < s_dump_disp_frm_buf . u4_y_ht ; i + + )
{
fwrite ( buf , 1 , s_dump_disp_frm_buf . u4_y_strd * 2 , ps_op_file ) ;
buf + = s_dump_disp_frm_buf . u4_y_strd * 2 ;
}
}
fflush ( ps_op_file ) ;
fflush ( ps_op_chksum_file ) ;
}
/*****************************************************************************/
/* */
/* Function Name : print_usage */
/* */
/* Description : Prints argument format */
/* */
/* */
/* Inputs : */
/* Globals : */
/* Processing : Prints argument format */
/* */
/* Outputs : */
/* Returns : */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
void print_usage ( void )
{
WORD32 i = 0 ;
WORD32 num_entries = sizeof ( argument_mapping ) / sizeof ( argument_t ) ;
printf ( " \n Usage: \n " ) ;
while ( i < num_entries )
{
printf ( " %-32s \t %s " , argument_mapping [ i ] . argument_name ,
argument_mapping [ i ] . description ) ;
i + + ;
}
}
/*****************************************************************************/
/* */
/* Function Name : get_argument */
/* */
/* Description : Gets argument for a given string */
/* */
/* */
/* Inputs : name */
/* Globals : */
/* Processing : Searches the given string in the array and returns */
/* appropriate argument ID */
/* */
/* Outputs : Argument ID */
/* Returns : Argument ID */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
ARGUMENT_T get_argument ( CHAR * name )
{
WORD32 i = 0 ;
WORD32 num_entries = sizeof ( argument_mapping ) / sizeof ( argument_t ) ;
while ( i < num_entries )
{
if ( ( 0 = = strcmp ( argument_mapping [ i ] . argument_name , name ) ) | |
( ( 0 = = strcmp ( argument_mapping [ i ] . argument_shortname , name ) ) & &
( 0 ! = strcmp ( argument_mapping [ i ] . argument_shortname , " -- " ) ) ) )
{
return argument_mapping [ i ] . argument ;
}
i + + ;
}
return INVALID ;
}
/*****************************************************************************/
/* */
/* Function Name : get_argument */
/* */
/* Description : Gets argument for a given string */
/* */
/* */
/* Inputs : name */
/* Globals : */
/* Processing : Searches the given string in the array and returns */
/* appropriate argument ID */
/* */
/* Outputs : Argument ID */
/* Returns : Argument ID */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
void parse_argument ( vid_dec_ctx_t * ps_app_ctx , CHAR * argument , CHAR * value )
{
ARGUMENT_T arg ;
arg = get_argument ( argument ) ;
switch ( arg )
{
case HELP :
print_usage ( ) ;
exit ( - 1 ) ;
case VERSION :
break ;
case INPUT_FILE :
sscanf ( value , " %s " , ps_app_ctx - > ac_ip_fname ) ;
//input_passed = 1;
break ;
case OUTPUT :
sscanf ( value , " %s " , ps_app_ctx - > ac_op_fname ) ;
break ;
case CHKSUM :
sscanf ( value , " %s " , ps_app_ctx - > ac_op_chksum_fname ) ;
break ;
case SAVE_OUTPUT :
sscanf ( value , " %d " , & ps_app_ctx - > u4_file_save_flag ) ;
break ;
case SAVE_CHKSUM :
sscanf ( value , " %d " , & ps_app_ctx - > u4_chksum_save_flag ) ;
break ;
case CHROMA_FORMAT :
if ( ( strcmp ( value , " YUV_420P " ) ) = = 0 )
ps_app_ctx - > e_output_chroma_format = IV_YUV_420P ;
else if ( ( strcmp ( value , " YUV_422ILE " ) ) = = 0 )
ps_app_ctx - > e_output_chroma_format = IV_YUV_422ILE ;
else if ( ( strcmp ( value , " RGB_565 " ) ) = = 0 )
ps_app_ctx - > e_output_chroma_format = IV_RGB_565 ;
else if ( ( strcmp ( value , " RGBA_8888 " ) ) = = 0 )
ps_app_ctx - > e_output_chroma_format = IV_RGBA_8888 ;
else if ( ( strcmp ( value , " YUV_420SP_UV " ) ) = = 0 )
ps_app_ctx - > e_output_chroma_format = IV_YUV_420SP_UV ;
else if ( ( strcmp ( value , " YUV_420SP_VU " ) ) = = 0 )
ps_app_ctx - > e_output_chroma_format = IV_YUV_420SP_VU ;
else
{
printf ( " \n Invalid colour format setting it to IV_YUV_420P \n " ) ;
ps_app_ctx - > e_output_chroma_format = IV_YUV_420P ;
}
break ;
case NUM_FRAMES :
sscanf ( value , " %d " , & ps_app_ctx - > u4_max_frm_ts ) ;
break ;
case NUM_CORES :
sscanf ( value , " %d " , & ps_app_ctx - > u4_num_cores ) ;
break ;
case DEGRADE_PICS :
sscanf ( value , " %d " , & ps_app_ctx - > i4_degrade_pics ) ;
break ;
case DEGRADE_TYPE :
sscanf ( value , " %d " , & ps_app_ctx - > i4_degrade_type ) ;
break ;
case SHARE_DISPLAY_BUF :
sscanf ( value , " %d " , & ps_app_ctx - > u4_share_disp_buf ) ;
break ;
case LOOPBACK :
sscanf ( value , " %d " , & ps_app_ctx - > loopback ) ;
break ;
case DISPLAY :
# if defined(SDL_DISPLAY) || defined(FBDEV_DISPLAY) || defined(INTEL_CE5300) || defined(IOS_DISPLAY)
sscanf ( value , " %d " , & ps_app_ctx - > display ) ;
# else
ps_app_ctx - > display = 0 ;
# endif
break ;
case FULLSCREEN :
sscanf ( value , " %d " , & ps_app_ctx - > full_screen ) ;
break ;
case FPS :
sscanf ( value , " %d " , & ps_app_ctx - > fps ) ;
if ( ps_app_ctx - > fps < = 0 )
ps_app_ctx - > fps = DEFAULT_FPS ;
break ;
case ARCH :
if ( ( strcmp ( value , " ARM_NONEON " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_ARM_NONEON ;
else if ( ( strcmp ( value , " ARM_A9Q " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_ARM_A9Q ;
else if ( ( strcmp ( value , " ARM_A7 " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_ARM_A7 ;
else if ( ( strcmp ( value , " ARM_A5 " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_ARM_A5 ;
else if ( ( strcmp ( value , " ARM_NEONINTR " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_ARM_NEONINTR ;
else if ( ( strcmp ( value , " X86_GENERIC " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_X86_GENERIC ;
else if ( ( strcmp ( value , " X86_SSSE3 " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_X86_SSSE3 ;
else if ( ( strcmp ( value , " X86_SSE42 " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_X86_SSE42 ;
else if ( ( strcmp ( value , " X86_AVX2 " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_X86_AVX2 ;
else if ( ( strcmp ( value , " MIPS_GENERIC " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_MIPS_GENERIC ;
else if ( ( strcmp ( value , " MIPS_32 " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_MIPS_32 ;
else if ( ( strcmp ( value , " ARMV8_GENERIC " ) ) = = 0 )
ps_app_ctx - > e_arch = ARCH_ARMV8_GENERIC ;
else
{
printf ( " \n Invalid Arch. Setting it to ARM_A9Q \n " ) ;
ps_app_ctx - > e_arch = ARCH_ARM_A9Q ;
}
break ;
case SOC :
if ( ( strcmp ( value , " GENERIC " ) ) = = 0 )
ps_app_ctx - > e_soc = SOC_GENERIC ;
else if ( ( strcmp ( value , " HISI_37X " ) ) = = 0 )
ps_app_ctx - > e_soc = SOC_HISI_37X ;
else
{
ps_app_ctx - > e_soc = atoi ( value ) ;
/*
printf ( " \n Invalid SOC. Setting it to GENERIC \n " ) ;
ps_app_ctx - > e_soc = SOC_GENERIC ;
*/
}
break ;
case PICLEN :
sscanf ( value , " %d " , & ps_app_ctx - > u4_piclen_flag ) ;
break ;
case PICLEN_FILE :
sscanf ( value , " %s " , ps_app_ctx - > ac_piclen_fname ) ;
break ;
case DISABLE_DEBLOCK_LEVEL :
sscanf ( value , " %d " , & ps_app_ctx - > u4_disable_dblk_level ) ;
break ;
case INVALID :
default :
printf ( " Ignoring argument : %s \n " , argument ) ;
break ;
}
}
/*****************************************************************************/
/* */
/* Function Name : read_cfg_file */
/* */
/* Description : Reads arguments from a configuration file */
/* */
/* */
/* Inputs : ps_app_ctx : Application context */
/* fp_cfg_file : Configuration file handle */
/* Globals : */
/* Processing : Parses the arguments and fills in the application context*/
/* */
/* Outputs : Arguments parsed */
/* Returns : None */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* */
/*****************************************************************************/
void read_cfg_file ( vid_dec_ctx_t * ps_app_ctx , FILE * fp_cfg_file )
{
CHAR line [ STRLENGTH ] ;
CHAR description [ STRLENGTH ] ;
CHAR value [ STRLENGTH ] ;
CHAR argument [ STRLENGTH ] ;
void * ret ;
while ( 0 = = feof ( fp_cfg_file ) )
{
line [ 0 ] = ' \0 ' ;
ret = fgets ( line , STRLENGTH , fp_cfg_file ) ;
if ( NULL = = ret )
break ;
argument [ 0 ] = ' \0 ' ;
/* Reading Input File Name */
sscanf ( line , " %s %s %s " , argument , value , description ) ;
if ( argument [ 0 ] = = ' \0 ' )
continue ;
parse_argument ( ps_app_ctx , argument , value ) ;
}
}
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ if Function name : dispq_producer_dequeue \ endif
*
* \ brief
* This function gets a free buffer index where display data can be written
* This is a blocking call and can be exited by setting quit to true in
* the application context
*
* \ param [ in ] ps_app_ctx : Pointer to application context
*
* \ return
* returns Next free buffer index for producer
*
* \ author
* Ittiam
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
WORD32 dispq_producer_dequeue ( vid_dec_ctx_t * ps_app_ctx )
{
WORD32 idx ;
/* If there is no free buffer wait */
while ( ( ( ps_app_ctx - > disp_q_wr_idx + 1 ) % NUM_DISPLAY_BUFFERS ) = = ps_app_ctx - > disp_q_rd_idx )
{
ithread_msleep ( 1 ) ;
if ( ps_app_ctx - > quit )
return ( - 1 ) ;
}
idx = ps_app_ctx - > disp_q_wr_idx ;
return ( idx ) ;
}
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ if Function name : dispq_producer_queue \ endif
*
* \ brief
* This function adds buffer which can be displayed
*
* \ param [ in ] ps_app_ctx : Pointer to application context
*
* \ return
* returns Next free buffer index for producer
*
* \ author
* Ittiam
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
WORD32 dispq_producer_queue ( vid_dec_ctx_t * ps_app_ctx )
{
ps_app_ctx - > disp_q_wr_idx + + ;
if ( ps_app_ctx - > disp_q_wr_idx = = NUM_DISPLAY_BUFFERS )
ps_app_ctx - > disp_q_wr_idx = 0 ;
return ( 0 ) ;
}
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ if Function name : dispq_consumer_dequeue \ endif
*
* \ brief
* This function gets a free buffer index where display data can be written
* This is a blocking call and can be exited by setting quit to true in
* the application context
*
* \ param [ in ] ps_app_ctx : Pointer to application context
*
* \ return
* returns Next free buffer index for producer
*
* \ author
* Ittiam
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
WORD32 dispq_consumer_dequeue ( vid_dec_ctx_t * ps_app_ctx )
{
WORD32 idx ;
/* If there is no free buffer wait */
while ( ps_app_ctx - > disp_q_wr_idx = = ps_app_ctx - > disp_q_rd_idx )
{
ithread_msleep ( 1 ) ;
if ( ps_app_ctx - > quit )
return ( - 1 ) ;
}
idx = ps_app_ctx - > disp_q_rd_idx ;
return ( idx ) ;
}
/*!
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* \ if Function name : dispq_producer_queue \ endif
*
* \ brief
* This function adds buffer which can be displayed
*
* \ param [ in ] ps_app_ctx : Pointer to application context
*
* \ return
* returns Next free buffer index for producer
*
* \ author
* Ittiam
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
WORD32 dispq_consumer_queue ( vid_dec_ctx_t * ps_app_ctx )
{
ps_app_ctx - > disp_q_rd_idx + + ;
if ( ps_app_ctx - > disp_q_rd_idx = = NUM_DISPLAY_BUFFERS )
ps_app_ctx - > disp_q_rd_idx = 0 ;
return ( 0 ) ;
}
/*****************************************************************************/
/* */
/* Function Name : display_thread */
/* */
/* Description : Thread to display the frame */
/* */
/* */
/* Inputs : pv_ctx : Application context */
/* */
/* Globals : */
/* Processing : Wait for a buffer to get produced by decoder and display */
/* that frame */
/* */
/* Outputs : */
/* Returns : None */
/* */
/* Issues : Pause followed by quit is making some deadlock condn */
/* If decoder was lagging initially and then fasten up, */
/* display will also go at faster rate till it reaches */
/* equilibrium wrt the initial time */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 05 2013 100578 Initial Version */
/* */
/*****************************************************************************/
WORD32 display_thread ( void * pv_ctx )
{
vid_dec_ctx_t * ps_app_ctx = ( vid_dec_ctx_t * ) pv_ctx ;
UWORD32 frm_duration ; /* in us */
UWORD32 current_time ;
UWORD32 expected_time ;
TIMER s_end_timer ;
TIMER s_first_frame_time ;
UWORD32 first_frame_displayed ;
# ifdef WINDOWS_TIMER
TIMER frequency ;
# endif
# ifdef WINDOWS_TIMER
QueryPerformanceFrequency ( & frequency ) ;
# endif
first_frame_displayed = 0 ;
expected_time = 0 ;
frm_duration = 1000000 / ps_app_ctx - > fps ;
/* Init display and allocate display buffers */
ps_app_ctx - > pv_disp_ctx = ( void * ) ps_app_ctx - > disp_init ( ps_app_ctx - > u4_pic_wd ,
ps_app_ctx - > u4_pic_ht ,
ps_app_ctx - > i4_screen_wd ,
ps_app_ctx - > i4_screen_ht ,
2015-08-04 09:55:15 +05:30
ps_app_ctx - > u4_pic_wd ,
ps_app_ctx - > u4_pic_ht ,
2015-03-13 21:24:58 +05:30
ps_app_ctx - > full_screen ,
& ps_app_ctx - > quit ,
& ps_app_ctx - > paused ) ;
ps_app_ctx - > alloc_disp_buffers ( ps_app_ctx - > pv_disp_ctx ) ;
ps_app_ctx - > display_init_done = 1 ;
while ( 1 )
{
WORD32 rd_idx ;
rd_idx = dispq_consumer_dequeue ( ps_app_ctx ) ;
if ( ps_app_ctx - > quit )
break ;
ps_app_ctx - > display_buffer ( ps_app_ctx - > pv_disp_ctx , rd_idx ) ;
if ( 0 = = first_frame_displayed )
{
GETTIME ( & s_first_frame_time ) ;
first_frame_displayed = 1 ;
}
/*********************************************************************/
/* Sleep based on the expected time of arrival of current buffer and */
/* the Current frame */
/*********************************************************************/
GETTIME ( & s_end_timer ) ;
ELAPSEDTIME ( s_first_frame_time , s_end_timer , current_time , frequency ) ;
/* time in micro second */
expected_time + = frm_duration ;
//printf("current_time %d expected_time %d diff %d \n", current_time, expected_time, (expected_time - current_time));
/* sleep for the diff. in time */
if ( current_time < expected_time )
ps_app_ctx - > disp_usleep ( ( expected_time - current_time ) ) ;
else
expected_time + = ( current_time - expected_time ) ;
dispq_consumer_queue ( ps_app_ctx ) ;
}
while ( 0 = = ps_app_ctx - > display_deinit_flag )
{
ps_app_ctx - > disp_usleep ( 1000 ) ;
}
ps_app_ctx - > disp_deinit ( ps_app_ctx - > pv_disp_ctx ) ;
return 0 ;
}
void output_write_stall ( CHAR * fname , UWORD32 cur_frm_idx )
{
const UWORD8 threshold = 64 ;
CHAR past_fname [ 1000 ] ;
FILE * fp_fast_file = NULL ;
if ( cur_frm_idx > = threshold )
{
sprintf ( past_fname , fname , cur_frm_idx - threshold ) ;
do
{
fp_fast_file = fopen ( past_fname , " rb " ) ;
if ( fp_fast_file ! = NULL )
{
fclose ( fp_fast_file ) ;
/* Wait until the resource is released by a third party app*/
ithread_msleep ( 5 ) ;
}
else
break ;
} while ( 1 ) ;
}
}
void flush_output ( iv_obj_t * codec_obj ,
vid_dec_ctx_t * ps_app_ctx ,
ivd_out_bufdesc_t * ps_out_buf ,
UWORD8 * pu1_bs_buf ,
UWORD32 * pu4_op_frm_ts ,
FILE * ps_op_file ,
FILE * ps_op_chksum_file ,
UWORD32 u4_ip_frm_ts ,
UWORD32 u4_bytes_remaining )
{
WORD32 ret ;
do
{
ivd_ctl_flush_ip_t s_ctl_ip ;
ivd_ctl_flush_op_t s_ctl_op ;
if ( * pu4_op_frm_ts > = ( ps_app_ctx - > u4_max_frm_ts + ps_app_ctx - > disp_delay ) )
break ;
s_ctl_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_ip . e_sub_cmd = IVD_CMD_CTL_FLUSH ;
s_ctl_ip . u4_size = sizeof ( ivd_ctl_flush_ip_t ) ;
s_ctl_op . u4_size = sizeof ( ivd_ctl_flush_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( ret ! = IV_SUCCESS )
{
printf ( " Error in Setting the decoder in flush mode \n " ) ;
}
if ( IV_SUCCESS = = ret )
{
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 ] =
ps_out_buf - > u4_min_out_buf_size [ 0 ] ;
s_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_out_buf - > u4_min_out_buf_size [ 2 ] ;
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 ] =
ps_out_buf - > pu1_bufs [ 2 ] ;
s_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 ) ;
/*****************************************************************************/
/* API Call: Video Decode */
/*****************************************************************************/
ret = ivd_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 )
{
CHAR cur_fname [ 1000 ] ;
CHAR * extn = NULL ;
/* The objective is to dump the decoded frames into separate files instead of
* dumping all the frames in one common file . Also , the number of dumped frames
* at any given instance of time cannot exceed ' frame_memory '
*/
if ( ps_app_ctx - > u4_file_save_flag )
{
/* Locate the position of extension yuv */
extn = strstr ( ps_app_ctx - > ac_op_fname , " %d " ) ;
if ( extn ! = NULL )
{
output_write_stall ( ps_app_ctx - > ac_op_fname , * pu4_op_frm_ts ) ;
/* Generate output file names */
sprintf ( cur_fname , ps_app_ctx - > ac_op_fname , * pu4_op_frm_ts ) ;
/* Open Output file */
ps_op_file = fopen ( cur_fname , " wb " ) ;
if ( NULL = = ps_op_file )
{
CHAR ac_error_str [ STRLENGTH ] ;
sprintf ( ac_error_str , " Could not open output file %s " ,
cur_fname ) ;
codec_exit ( ac_error_str ) ;
}
}
}
dump_output ( ps_app_ctx , & ( s_video_decode_op . s_disp_frm_buf ) ,
s_video_decode_op . u4_disp_buf_id , ps_op_file ,
ps_op_chksum_file ,
* pu4_op_frm_ts , ps_app_ctx - > u4_file_save_flag ,
ps_app_ctx - > u4_chksum_save_flag ) ;
if ( extn ! = NULL )
fclose ( ps_op_file ) ;
( * pu4_op_frm_ts ) + + ;
}
}
}
while ( IV_SUCCESS = = ret ) ;
}
# ifdef X86_MINGW
void sigsegv_handler ( )
{
printf ( " Segmentation fault, Exiting.. \n " ) ;
exit ( - 1 ) ;
}
# endif
UWORD32 default_get_stride ( void )
{
return 0 ;
}
IV_COLOR_FORMAT_T default_get_color_fmt ( void )
{
return IV_YUV_420P ;
}
/*****************************************************************************/
/* */
/* Function Name : main */
/* */
/* Description : Application to demonstrate codec API */
/* */
/* */
/* Inputs : argc - Number of arguments */
/* argv[] - Arguments */
/* Globals : */
/* Processing : Shows how to use create, process, control and delete */
/* */
/* Outputs : Codec output in a file */
/* Returns : */
/* */
/* Issues : Assumes both PROFILE_ENABLE to be */
/* defined for multithread decode-display working */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes */
/* 07 09 2012 100189 Initial Version */
/* 09 05 2013 100578 Multithread decode-display */
/*****************************************************************************/
# ifdef IOS
int h264dec_main ( char * homedir , char * documentdir , int screen_wd , int screen_ht )
# else
int main ( WORD32 argc , CHAR * argv [ ] )
# endif
{
CHAR ac_cfg_fname [ STRLENGTH ] ;
FILE * fp_cfg_file = NULL ;
FILE * ps_piclen_file = NULL ;
FILE * ps_ip_file = NULL ;
FILE * ps_op_file = NULL ;
FILE * ps_op_chksum_file = NULL ;
WORD32 ret ;
CHAR ac_error_str [ STRLENGTH ] ;
vid_dec_ctx_t s_app_ctx ;
2015-09-02 09:01:40 +05:30
UWORD8 * pu1_bs_buf = NULL ;
2015-03-13 21:24:58 +05:30
ivd_out_bufdesc_t * ps_out_buf ;
UWORD32 u4_num_bytes_dec = 0 ;
UWORD32 file_pos = 0 ;
2015-08-04 09:55:15 +05:30
2015-03-13 21:24:58 +05:30
UWORD32 u4_ip_frm_ts = 0 , u4_op_frm_ts = 0 ;
WORD32 u4_bytes_remaining = 0 ;
UWORD32 i ;
UWORD32 u4_ip_buf_len ;
UWORD32 frm_cnt = 0 ;
WORD32 total_bytes_comsumed ;
UWORD32 max_op_frm_ts ;
2015-06-27 00:20:33 +03:00
UWORD32 u4_num_disp_bufs_with_dec ;
2015-03-13 21:24:58 +05:30
# ifdef PROFILE_ENABLE
UWORD32 u4_tot_cycles = 0 ;
UWORD32 u4_tot_fmt_cycles = 0 ;
UWORD32 peak_window [ PEAK_WINDOW_SIZE ] ;
UWORD32 peak_window_idx = 0 ;
UWORD32 peak_avg_max = 0 ;
# ifdef INTEL_CE5300
UWORD32 time_consumed = 0 ;
UWORD32 bytes_consumed = 0 ;
# endif
# endif
# ifdef WINDOWS_TIMER
TIMER frequency ;
# endif
WORD32 width = 0 , height = 0 ;
iv_obj_t * codec_obj ;
# if defined(GPU_BUILD) && !defined(X86)
// int ioctl_init();
// ioctl_init();
# endif
# ifdef X86_MINGW
//For getting printfs without any delay
setvbuf ( stdout , NULL , _IONBF , 0 ) ;
setvbuf ( stderr , NULL , _IONBF , 0 ) ;
# endif
# ifdef IOS
sprintf ( filename_trace , " %s/iostrace.txt " , homedir ) ;
printf ( " \n trace file name = %s " , filename_trace ) ;
# endif
# ifdef X86_MINGW
{
signal ( SIGSEGV , sigsegv_handler ) ;
}
# endif
# ifndef IOS
/* Usage */
if ( argc < 2 )
{
printf ( " Using test.cfg as configuration file \n " ) ;
strcpy ( ac_cfg_fname , " test.cfg " ) ;
}
else if ( argc = = 2 )
{
strcpy ( ac_cfg_fname , argv [ 1 ] ) ;
}
# else
strcpy ( ac_cfg_fname , " test.cfg " ) ;
# endif
/***********************************************************************/
/* Initialize Application parameters */
/***********************************************************************/
strcpy ( s_app_ctx . ac_ip_fname , " \0 " ) ;
s_app_ctx . dump_q_wr_idx = 0 ;
s_app_ctx . dump_q_rd_idx = 0 ;
s_app_ctx . display_thread_created = 0 ;
s_app_ctx . disp_q_wr_idx = 0 ;
s_app_ctx . disp_q_rd_idx = 0 ;
s_app_ctx . disp_delay = 0 ;
s_app_ctx . loopback = 0 ;
s_app_ctx . display = 0 ;
s_app_ctx . full_screen = 0 ;
s_app_ctx . u4_piclen_flag = 0 ;
s_app_ctx . fps = DEFAULT_FPS ;
file_pos = 0 ;
total_bytes_comsumed = 0 ;
u4_ip_frm_ts = 0 ;
u4_op_frm_ts = 0 ;
# ifdef PROFILE_ENABLE
memset ( peak_window , 0 , sizeof ( WORD32 ) * PEAK_WINDOW_SIZE ) ;
# endif
s_app_ctx . u4_share_disp_buf = DEFAULT_SHARE_DISPLAY_BUF ;
s_app_ctx . u4_num_cores = DEFAULT_NUM_CORES ;
s_app_ctx . i4_degrade_type = 0 ;
s_app_ctx . i4_degrade_pics = 0 ;
s_app_ctx . e_arch = ARCH_ARM_A9Q ;
s_app_ctx . e_soc = SOC_GENERIC ;
s_app_ctx . u4_strd = STRIDE ;
s_app_ctx . display_thread_handle = malloc ( ithread_get_handle_size ( ) ) ;
s_app_ctx . quit = 0 ;
s_app_ctx . paused = 0 ;
//s_app_ctx.u4_output_present = 0;
s_app_ctx . get_stride = & default_get_stride ;
s_app_ctx . get_color_fmt = & default_get_color_fmt ;
/* Set function pointers for display */
# ifdef SDL_DISPLAY
s_app_ctx . disp_init = & sdl_disp_init ;
s_app_ctx . alloc_disp_buffers = & sdl_alloc_disp_buffers ;
s_app_ctx . display_buffer = & sdl_display ;
s_app_ctx . set_disp_buffers = & sdl_set_disp_buffers ;
s_app_ctx . disp_deinit = & sdl_disp_deinit ;
s_app_ctx . disp_usleep = & sdl_disp_usleep ;
s_app_ctx . get_color_fmt = & sdl_get_color_fmt ;
s_app_ctx . get_stride = & sdl_get_stride ;
# endif
# ifdef FBDEV_DISPLAY
s_app_ctx . disp_init = & fbd_disp_init ;
s_app_ctx . alloc_disp_buffers = & fbd_alloc_disp_buffers ;
s_app_ctx . display_buffer = & fbd_display ;
s_app_ctx . set_disp_buffers = & fbd_set_disp_buffers ;
s_app_ctx . disp_deinit = & fbd_disp_deinit ;
s_app_ctx . disp_usleep = & fbd_disp_usleep ;
s_app_ctx . get_color_fmt = & fbd_get_color_fmt ;
s_app_ctx . get_stride = & fbd_get_stride ;
# endif
# ifdef INTEL_CE5300
s_app_ctx . disp_init = & gdl_disp_init ;
s_app_ctx . alloc_disp_buffers = & gdl_alloc_disp_buffers ;
s_app_ctx . display_buffer = & gdl_display ;
s_app_ctx . set_disp_buffers = & gdl_set_disp_buffers ;
s_app_ctx . disp_deinit = & gdl_disp_deinit ;
s_app_ctx . disp_usleep = & gdl_disp_usleep ;
s_app_ctx . get_color_fmt = & gdl_get_color_fmt ;
s_app_ctx . get_stride = & gdl_get_stride ;
# endif
# ifdef IOS_DISPLAY
s_app_ctx . disp_init = & ios_disp_init ;
s_app_ctx . alloc_disp_buffers = & ios_alloc_disp_buffers ;
s_app_ctx . display_buffer = & ios_display ;
s_app_ctx . set_disp_buffers = & ios_set_disp_buffers ;
s_app_ctx . disp_deinit = & ios_disp_deinit ;
s_app_ctx . disp_usleep = & ios_disp_usleep ;
s_app_ctx . get_color_fmt = & ios_get_color_fmt ;
s_app_ctx . get_stride = & ios_get_stride ;
# endif
s_app_ctx . display_deinit_flag = 0 ;
s_app_ctx . e_output_chroma_format = IV_YUV_420SP_UV ;
/*************************************************************************/
/* Parse arguments */
/*************************************************************************/
# ifndef IOS
/* Read command line arguments */
if ( argc > 2 )
{
for ( i = 1 ; i < ( UWORD32 ) argc ; i + = 2 )
{
if ( CONFIG = = get_argument ( argv [ i ] ) )
{
strcpy ( ac_cfg_fname , argv [ i + 1 ] ) ;
if ( ( fp_cfg_file = fopen ( ac_cfg_fname , " r " ) ) = = NULL )
{
sprintf ( ac_error_str , " Could not open Configuration file %s " ,
ac_cfg_fname ) ;
codec_exit ( ac_error_str ) ;
}
read_cfg_file ( & s_app_ctx , fp_cfg_file ) ;
fclose ( fp_cfg_file ) ;
}
else
{
parse_argument ( & s_app_ctx , argv [ i ] , argv [ i + 1 ] ) ;
}
}
}
else
{
if ( ( fp_cfg_file = fopen ( ac_cfg_fname , " r " ) ) = = NULL )
{
sprintf ( ac_error_str , " Could not open Configuration file %s " ,
ac_cfg_fname ) ;
codec_exit ( ac_error_str ) ;
}
read_cfg_file ( & s_app_ctx , fp_cfg_file ) ;
fclose ( fp_cfg_file ) ;
}
# else
sprintf ( filename_with_path , " %s/%s " , homedir , ac_cfg_fname ) ;
if ( ( fp_cfg_file = fopen ( filename_with_path , " r " ) ) = = NULL )
{
sprintf ( ac_error_str , " Could not open Configuration file %s " ,
ac_cfg_fname ) ;
codec_exit ( ac_error_str ) ;
}
read_cfg_file ( & s_app_ctx , fp_cfg_file ) ;
fclose ( fp_cfg_file ) ;
# endif
# ifdef PRINT_PICSIZE
/* If the binary is used for only getting number of bytes in each picture, then disable the following features */
s_app_ctx . u4_piclen_flag = 0 ;
s_app_ctx . u4_file_save_flag = 0 ;
s_app_ctx . u4_chksum_save_flag = 0 ;
s_app_ctx . i4_degrade_pics = 0 ;
s_app_ctx . i4_degrade_type = 0 ;
s_app_ctx . loopback = 0 ;
s_app_ctx . u4_share_disp_buf = 0 ;
s_app_ctx . display = 0 ;
# endif
/* If display is enabled, then turn off shared mode and get color format that is supported by display */
if ( 1 = = s_app_ctx . display )
{
s_app_ctx . u4_share_disp_buf = 0 ;
s_app_ctx . e_output_chroma_format = s_app_ctx . get_color_fmt ( ) ;
}
if ( strcmp ( s_app_ctx . ac_ip_fname , " \0 " ) = = 0 )
{
printf ( " \n No input file given for decoding \n " ) ;
exit ( - 1 ) ;
}
/***********************************************************************/
/* create the file object for input file */
/***********************************************************************/
# ifdef IOS
sprintf ( filename_with_path , " %s/%s " , homedir , s_app_ctx . ac_ip_fname ) ;
ps_ip_file = fopen ( filename_with_path , " rb " ) ;
# else
ps_ip_file = fopen ( s_app_ctx . ac_ip_fname , " rb " ) ;
# endif
if ( NULL = = ps_ip_file )
{
sprintf ( ac_error_str , " Could not open input file %s " ,
s_app_ctx . ac_ip_fname ) ;
codec_exit ( ac_error_str ) ;
}
/***********************************************************************/
/* create the file object for input file */
/***********************************************************************/
if ( 1 = = s_app_ctx . u4_piclen_flag )
{
# ifdef IOS
sprintf ( filename_with_path , " %s/%s " , homedir , s_app_ctx . ac_piclen_fname ) ;
ps_piclen_file = fopen ( filename_with_path , " rb " ) ;
# else
ps_piclen_file = fopen ( s_app_ctx . ac_piclen_fname , " rb " ) ;
# endif
if ( NULL = = ps_piclen_file )
{
sprintf ( ac_error_str , " Could not open piclen file %s " ,
s_app_ctx . ac_piclen_fname ) ;
codec_exit ( ac_error_str ) ;
}
}
/***********************************************************************/
/* create the file object for output file */
/***********************************************************************/
/* If the filename does not contain %d, then output will be dumped to
a single file and it is opened here */
if ( ( 1 = = s_app_ctx . u4_file_save_flag ) & & ( strstr ( s_app_ctx . ac_op_fname , " %d " ) = = NULL ) )
{
# ifdef IOS
sprintf ( filename_with_path , " %s/%s " , documentdir , s_app_ctx . ac_op_fname ) ;
ps_op_file = fopen ( filename_with_path , " wb " ) ;
# else
ps_op_file = fopen ( s_app_ctx . ac_op_fname , " wb " ) ;
# endif
if ( NULL = = ps_op_file )
{
sprintf ( ac_error_str , " Could not open output file %s " ,
s_app_ctx . ac_op_fname ) ;
codec_exit ( ac_error_str ) ;
}
}
/***********************************************************************/
/* create the file object for check sum file */
/***********************************************************************/
if ( 1 = = s_app_ctx . u4_chksum_save_flag )
{
# if IOS
sprintf ( filename_with_path , " %s/%s " , documentdir , s_app_ctx . ac_op_chksum_fname ) ;
ps_op_chksum_file = fopen ( filename_with_path , " wb " ) ;
# else
ps_op_chksum_file = fopen ( s_app_ctx . ac_op_chksum_fname , " wb " ) ;
# endif
if ( NULL = = ps_op_chksum_file )
{
sprintf ( ac_error_str , " Could not open check sum file %s " ,
s_app_ctx . ac_op_chksum_fname ) ;
codec_exit ( ac_error_str ) ;
}
}
/***********************************************************************/
/* Create decoder instance */
/***********************************************************************/
{
ps_out_buf = ( ivd_out_bufdesc_t * ) malloc ( sizeof ( ivd_out_bufdesc_t ) ) ;
/*****************************************************************************/
/* API Call: Initialize the Decoder */
/*****************************************************************************/
{
2015-08-04 09:55:15 +05:30
ih264d_create_ip_t s_create_ip ;
ih264d_create_op_t s_create_op ;
2015-03-13 21:24:58 +05:30
void * fxns = & ivd_api_function ;
2015-08-04 09:55:15 +05:30
s_create_ip . s_ivd_create_ip_t . e_cmd = IVD_CMD_CREATE ;
s_create_ip . s_ivd_create_ip_t . u4_share_disp_buf = s_app_ctx . u4_share_disp_buf ;
s_create_ip . s_ivd_create_ip_t . e_output_format = ( IV_COLOR_FORMAT_T ) s_app_ctx . e_output_chroma_format ;
s_create_ip . s_ivd_create_ip_t . pf_aligned_alloc = ih264a_aligned_malloc ;
s_create_ip . s_ivd_create_ip_t . pf_aligned_free = ih264a_aligned_free ;
s_create_ip . s_ivd_create_ip_t . pv_mem_ctxt = NULL ;
s_create_ip . s_ivd_create_ip_t . u4_size = sizeof ( ih264d_create_ip_t ) ;
s_create_op . s_ivd_create_op_t . u4_size = sizeof ( ih264d_create_op_t ) ;
2015-03-13 21:24:58 +05:30
2015-08-04 09:55:15 +05:30
ret = ivd_api_function ( NULL , ( void * ) & s_create_ip ,
( void * ) & s_create_op ) ;
2015-03-13 21:24:58 +05:30
if ( ret ! = IV_SUCCESS )
{
2015-08-04 09:55:15 +05:30
sprintf ( ac_error_str , " Error in Create %8x \n " ,
s_create_op . s_ivd_create_op_t . u4_error_code ) ;
2015-03-13 21:24:58 +05:30
codec_exit ( ac_error_str ) ;
}
2015-08-04 09:55:15 +05:30
codec_obj = ( iv_obj_t * ) s_create_op . s_ivd_create_op_t . pv_handle ;
codec_obj - > pv_fxns = fxns ;
codec_obj - > u4_size = sizeof ( iv_obj_t ) ;
s_app_ctx . cocodec_obj = codec_obj ;
2015-06-03 07:26:32 -07:00
/*****************************************************************************/
/* set stride */
/*****************************************************************************/
{
ivd_ctl_set_config_ip_t s_ctl_ip ;
ivd_ctl_set_config_op_t s_ctl_op ;
s_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 ;
2015-08-04 09:55:15 +05:30
s_ctl_ip . e_frm_out_mode = IVD_DISPLAY_FRAME_OUT ;
2015-06-03 07:26:32 -07:00
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 ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str ,
" \n Error in setting the stride " ) ;
codec_exit ( ac_error_str ) ;
}
}
2015-03-13 21:24:58 +05:30
}
}
/*************************************************************************/
/* set num of cores */
/*************************************************************************/
{
ih264d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip ;
ih264d_ctl_set_num_cores_op_t s_ctl_set_cores_op ;
s_ctl_set_cores_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_set_cores_ip . e_sub_cmd = ( IVD_CONTROL_API_COMMAND_TYPE_T ) IH264D_CMD_CTL_SET_NUM_CORES ;
s_ctl_set_cores_ip . u4_num_cores = s_app_ctx . u4_num_cores ;
s_ctl_set_cores_ip . u4_size = sizeof ( ih264d_ctl_set_num_cores_ip_t ) ;
s_ctl_set_cores_op . u4_size = sizeof ( ih264d_ctl_set_num_cores_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_set_cores_ip ,
( void * ) & s_ctl_set_cores_op ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str , " \n Error in setting number of cores " ) ;
codec_exit ( ac_error_str ) ;
}
}
/*************************************************************************/
/* set processsor */
/*************************************************************************/
{
ih264d_ctl_set_processor_ip_t s_ctl_set_num_processor_ip ;
ih264d_ctl_set_processor_op_t s_ctl_set_num_processor_op ;
s_ctl_set_num_processor_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_set_num_processor_ip . e_sub_cmd = ( IVD_CONTROL_API_COMMAND_TYPE_T ) IH264D_CMD_CTL_SET_PROCESSOR ;
s_ctl_set_num_processor_ip . u4_arch = s_app_ctx . e_arch ;
s_ctl_set_num_processor_ip . u4_soc = s_app_ctx . e_soc ;
s_ctl_set_num_processor_ip . u4_size = sizeof ( ih264d_ctl_set_processor_ip_t ) ;
s_ctl_set_num_processor_op . u4_size = sizeof ( ih264d_ctl_set_processor_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_set_num_processor_ip ,
( void * ) & s_ctl_set_num_processor_op ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str , " \n Error in setting Processor type " ) ;
codec_exit ( ac_error_str ) ;
}
}
2015-09-02 09:01:40 +05:30
flush_output ( codec_obj , & s_app_ctx , ps_out_buf ,
pu1_bs_buf , & u4_op_frm_ts ,
ps_op_file , ps_op_chksum_file ,
u4_ip_frm_ts , u4_bytes_remaining ) ;
2015-03-13 21:24:58 +05:30
/*****************************************************************************/
/* 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 ;
2015-08-04 09:55:15 +05:30
{
ivd_ctl_set_config_ip_t s_ctl_ip ;
ivd_ctl_set_config_op_t s_ctl_op ;
s_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 ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str ,
" \n Error in setting the codec in header decode mode " ) ;
codec_exit ( ac_error_str ) ;
}
}
/* Allocate input buffer for header */
u4_ip_buf_len = 256 * 1024 ;
pu1_bs_buf = ( UWORD8 * ) malloc ( u4_ip_buf_len ) ;
if ( pu1_bs_buf = = NULL )
2015-03-13 21:24:58 +05:30
{
sprintf ( ac_error_str ,
2015-08-04 09:55:15 +05:30
" \n Allocation failure for input buffer of i4_size %d " ,
u4_ip_buf_len ) ;
2015-03-13 21:24:58 +05:30
codec_exit ( ac_error_str ) ;
}
do
{
WORD32 numbytes ;
2015-08-04 09:55:15 +05:30
2015-03-13 21:24:58 +05:30
if ( 0 = = s_app_ctx . u4_piclen_flag )
{
fseek ( ps_ip_file , file_pos , SEEK_SET ) ;
numbytes = u4_ip_buf_len ;
}
else
{
WORD32 entries ;
entries = fscanf ( ps_piclen_file , " %d \n " , & numbytes ) ;
if ( 1 ! = entries )
numbytes = u4_ip_buf_len ;
}
u4_bytes_remaining = fread ( pu1_bs_buf , sizeof ( UWORD8 ) , numbytes ,
ps_ip_file ) ;
if ( 0 = = u4_bytes_remaining )
{
sprintf ( ac_error_str , " \n Unable to read from input file " ) ;
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 ) ;
/*****************************************************************************/
/* API Call: Header Decode */
/*****************************************************************************/
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_video_decode_ip ,
( void * ) & s_video_decode_op ) ;
if ( ret ! = IV_SUCCESS )
{
2015-06-03 07:26:32 -07:00
printf ( " Error in header decode 0x%x \n " , s_video_decode_op . u4_error_code ) ;
2015-03-13 21:24:58 +05:30
// codec_exit(ac_error_str);
}
u4_num_bytes_dec = s_video_decode_op . u4_num_bytes_consumed ;
# ifndef PROFILE_ENABLE
printf ( " %d \n " , s_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 ;
2015-08-04 09:55:15 +05:30
free ( pu1_bs_buf ) ;
2015-03-13 21:24:58 +05:30
# if IOS_DISPLAY
s_app_ctx . i4_screen_wd = screen_wd ;
s_app_ctx . i4_screen_ht = screen_ht ;
# endif
2015-08-04 09:55:15 +05:30
{
ivd_ctl_getbufinfo_ip_t s_ctl_ip ;
ivd_ctl_getbufinfo_op_t s_ctl_op ;
WORD32 outlen = 0 ;
s_ctl_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_ip . e_sub_cmd = IVD_CMD_CTL_GETBUFINFO ;
s_ctl_ip . u4_size = sizeof ( ivd_ctl_getbufinfo_ip_t ) ;
s_ctl_op . u4_size = sizeof ( ivd_ctl_getbufinfo_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str , " Error in Get Buf Info %x " , s_ctl_op . u4_error_code ) ;
codec_exit ( ac_error_str ) ;
}
/* Allocate bitstream buffer */
u4_ip_buf_len = s_ctl_op . u4_min_in_buf_size [ 0 ] ;
# ifdef ADAPTIVE_TEST
u4_ip_buf_len = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 3 > > 1 ;
# endif
pu1_bs_buf = ( UWORD8 * ) malloc ( u4_ip_buf_len ) ;
if ( pu1_bs_buf = = NULL )
{
sprintf ( ac_error_str ,
" \n Allocation failure for input buffer of i4_size %d " ,
u4_ip_buf_len ) ;
codec_exit ( ac_error_str ) ;
}
s_app_ctx . num_disp_buf = s_ctl_op . u4_num_disp_bufs ;
/* Allocate output buffer only if display buffers are not shared */
/* Or if shared and output is 420P */
if ( ( 0 = = s_app_ctx . u4_share_disp_buf ) | | ( IV_YUV_420P = = s_app_ctx . e_output_chroma_format ) )
{
# ifdef ADAPTIVE_TEST
switch ( s_app_ctx . e_output_chroma_format )
{
case IV_YUV_420P :
{
s_ctl_op . u4_min_out_buf_size [ 0 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT ;
s_ctl_op . u4_min_out_buf_size [ 1 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT > > 2 ;
s_ctl_op . u4_min_out_buf_size [ 2 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT > > 2 ;
break ;
}
case IV_YUV_420SP_UV :
case IV_YUV_420SP_VU :
{
s_ctl_op . u4_min_out_buf_size [ 0 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT ;
s_ctl_op . u4_min_out_buf_size [ 1 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT > > 1 ;
s_ctl_op . u4_min_out_buf_size [ 2 ] = 0 ;
break ;
}
case IV_YUV_422ILE :
{
s_ctl_op . u4_min_out_buf_size [ 0 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 2 ;
s_ctl_op . u4_min_out_buf_size [ 1 ] = 0 ;
s_ctl_op . u4_min_out_buf_size [ 2 ] = 0 ;
break ;
}
case IV_RGBA_8888 :
{
s_ctl_op . u4_min_out_buf_size [ 0 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 4 ;
s_ctl_op . u4_min_out_buf_size [ 1 ] = 0 ;
s_ctl_op . u4_min_out_buf_size [ 2 ] = 0 ;
break ;
}
case IV_RGB_565 :
{
s_ctl_op . u4_min_out_buf_size [ 0 ] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 2 ;
s_ctl_op . u4_min_out_buf_size [ 1 ] = 0 ;
s_ctl_op . u4_min_out_buf_size [ 2 ] = 0 ;
break ;
}
default :
break ;
}
# endif
ps_out_buf - > u4_min_out_buf_size [ 0 ] =
s_ctl_op . u4_min_out_buf_size [ 0 ] ;
ps_out_buf - > u4_min_out_buf_size [ 1 ] =
s_ctl_op . u4_min_out_buf_size [ 1 ] ;
ps_out_buf - > u4_min_out_buf_size [ 2 ] =
s_ctl_op . u4_min_out_buf_size [ 2 ] ;
outlen = s_ctl_op . u4_min_out_buf_size [ 0 ] ;
if ( s_ctl_op . u4_min_num_out_bufs > 1 )
outlen + = s_ctl_op . u4_min_out_buf_size [ 1 ] ;
if ( s_ctl_op . u4_min_num_out_bufs > 2 )
outlen + = s_ctl_op . u4_min_out_buf_size [ 2 ] ;
ps_out_buf - > pu1_bufs [ 0 ] = ( UWORD8 * ) malloc ( outlen ) ;
if ( ps_out_buf - > pu1_bufs [ 0 ] = = NULL )
{
sprintf ( ac_error_str ,
" \n Allocation failure for output buffer of i4_size %d " ,
outlen ) ;
codec_exit ( ac_error_str ) ;
}
if ( s_ctl_op . u4_min_num_out_bufs > 1 )
ps_out_buf - > pu1_bufs [ 1 ] = ps_out_buf - > pu1_bufs [ 0 ]
+ ( s_ctl_op . u4_min_out_buf_size [ 0 ] ) ;
if ( s_ctl_op . u4_min_num_out_bufs > 2 )
ps_out_buf - > pu1_bufs [ 2 ] = ps_out_buf - > pu1_bufs [ 1 ]
+ ( s_ctl_op . u4_min_out_buf_size [ 1 ] ) ;
ps_out_buf - > u4_num_bufs = s_ctl_op . u4_min_num_out_bufs ;
}
# ifdef APP_EXTRA_BUFS
s_app_ctx . disp_delay = EXTRA_DISP_BUFFERS ;
s_ctl_op . u4_num_disp_bufs + = EXTRA_DISP_BUFFERS ;
# endif
/*****************************************************************************/
/* API Call: Allocate display buffers for display buffer shared case */
/*****************************************************************************/
for ( i = 0 ; i < s_ctl_op . u4_num_disp_bufs ; i + + )
{
s_app_ctx . s_disp_buffers [ i ] . u4_min_out_buf_size [ 0 ] =
s_ctl_op . u4_min_out_buf_size [ 0 ] ;
s_app_ctx . s_disp_buffers [ i ] . u4_min_out_buf_size [ 1 ] =
s_ctl_op . u4_min_out_buf_size [ 1 ] ;
s_app_ctx . s_disp_buffers [ i ] . u4_min_out_buf_size [ 2 ] =
s_ctl_op . u4_min_out_buf_size [ 2 ] ;
outlen = s_ctl_op . u4_min_out_buf_size [ 0 ] ;
if ( s_ctl_op . u4_min_num_out_bufs > 1 )
outlen + = s_ctl_op . u4_min_out_buf_size [ 1 ] ;
if ( s_ctl_op . u4_min_num_out_bufs > 2 )
outlen + = s_ctl_op . u4_min_out_buf_size [ 2 ] ;
s_app_ctx . s_disp_buffers [ i ] . pu1_bufs [ 0 ] = ( UWORD8 * ) malloc ( outlen ) ;
if ( s_app_ctx . s_disp_buffers [ i ] . pu1_bufs [ 0 ] = = NULL )
{
sprintf ( ac_error_str ,
" \n Allocation failure for output buffer of i4_size %d " ,
outlen ) ;
codec_exit ( ac_error_str ) ;
}
if ( s_ctl_op . u4_min_num_out_bufs > 1 )
s_app_ctx . s_disp_buffers [ i ] . pu1_bufs [ 1 ] =
s_app_ctx . s_disp_buffers [ i ] . pu1_bufs [ 0 ]
+ ( s_ctl_op . u4_min_out_buf_size [ 0 ] ) ;
if ( s_ctl_op . u4_min_num_out_bufs > 2 )
s_app_ctx . s_disp_buffers [ i ] . pu1_bufs [ 2 ] =
s_app_ctx . s_disp_buffers [ i ] . pu1_bufs [ 1 ]
+ ( s_ctl_op . u4_min_out_buf_size [ 1 ] ) ;
s_app_ctx . s_disp_buffers [ i ] . u4_num_bufs =
s_ctl_op . u4_min_num_out_bufs ;
}
s_app_ctx . num_disp_buf = s_ctl_op . u4_num_disp_bufs ;
}
2015-03-13 21:24:58 +05:30
/* Create display thread and wait for the display buffers to be initialized */
if ( 1 = = s_app_ctx . display )
{
if ( 0 = = s_app_ctx . display_thread_created )
{
s_app_ctx . display_init_done = 0 ;
ithread_create ( s_app_ctx . display_thread_handle , NULL ,
( void * ) & display_thread , ( void * ) & s_app_ctx ) ;
s_app_ctx . display_thread_created = 1 ;
while ( 1 )
{
if ( s_app_ctx . display_init_done )
break ;
ithread_msleep ( 1 ) ;
}
}
s_app_ctx . u4_strd = s_app_ctx . get_stride ( ) ;
}
}
/*************************************************************************/
/* Get actual number of output buffers requried, which is dependent */
/* on ps_bitstrm properties such as width, height and level etc */
/* This is needed mainly for shared display mode */
/*************************************************************************/
//if(1 == s_app_ctx.u4_share_disp_buf)
{
/*****************************************************************************/
/* API Call: Send the allocated display buffers to codec */
/*****************************************************************************/
{
ivd_set_display_frame_ip_t s_set_display_frame_ip ;
ivd_set_display_frame_op_t s_set_display_frame_op ;
s_set_display_frame_ip . e_cmd = IVD_CMD_SET_DISPLAY_FRAME ;
s_set_display_frame_ip . u4_size = sizeof ( ivd_set_display_frame_ip_t ) ;
s_set_display_frame_op . u4_size = sizeof ( ivd_set_display_frame_op_t ) ;
s_set_display_frame_ip . num_disp_bufs = s_app_ctx . num_disp_buf ;
memcpy ( & ( s_set_display_frame_ip . s_disp_buffer ) ,
& ( s_app_ctx . s_disp_buffers ) ,
2015-06-09 15:54:31 +05:30
s_app_ctx . num_disp_buf * sizeof ( ivd_out_bufdesc_t ) ) ;
2015-03-13 21:24:58 +05:30
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj ,
( void * ) & s_set_display_frame_ip ,
( void * ) & s_set_display_frame_op ) ;
if ( IV_SUCCESS ! = ret )
{
sprintf ( ac_error_str , " Error in Set display frame " ) ;
codec_exit ( ac_error_str ) ;
}
}
}
/*************************************************************************/
/* Get frame dimensions for display buffers such as x_offset,y_offset */
/* etc. This information might be needed to set display buffer */
/* offsets in case of shared display buffer mode */
/*************************************************************************/
{
ih264d_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip ;
ih264d_ctl_get_frame_dimensions_op_t s_ctl_get_frame_dimensions_op ;
s_ctl_get_frame_dimensions_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_get_frame_dimensions_ip . e_sub_cmd =
( IVD_CONTROL_API_COMMAND_TYPE_T ) IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS ;
s_ctl_get_frame_dimensions_ip . u4_size =
sizeof ( ih264d_ctl_get_frame_dimensions_ip_t ) ;
s_ctl_get_frame_dimensions_op . u4_size =
sizeof ( ih264d_ctl_get_frame_dimensions_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_get_frame_dimensions_ip ,
( void * ) & s_ctl_get_frame_dimensions_op ) ;
if ( IV_SUCCESS ! = ret )
{
sprintf ( ac_error_str , " Error in Get buffer Dimensions " ) ;
codec_exit ( ac_error_str ) ;
}
/*
printf ( " Frame offsets due to padding \n " ) ;
printf ( " s_ctl_get_frame_dimensions_op.x_offset[0] %d s_ctl_get_frame_dimensions_op.y_offset[0] %d \n " ,
s_ctl_get_frame_dimensions_op . u4_x_offset [ 0 ] ,
s_ctl_get_frame_dimensions_op . u4_y_offset [ 0 ] ) ;
*/
}
/*************************************************************************/
/* Set the decoder in frame decode mode. It was set in header decode */
/* mode earlier */
/*************************************************************************/
{
ivd_ctl_set_config_ip_t s_ctl_ip ;
ivd_ctl_set_config_op_t s_ctl_op ;
s_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_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 = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip , ( void * ) & s_ctl_op ) ;
if ( IV_SUCCESS ! = ret )
{
sprintf ( ac_error_str , " Error in Set Parameters " ) ;
//codec_exit(ac_error_str);
}
}
/*************************************************************************/
/* If required disable deblocking and sao at given level */
/*************************************************************************/
set_degrade ( codec_obj , s_app_ctx . i4_degrade_type , s_app_ctx . i4_degrade_pics ) ;
# ifdef WINDOWS_TIMER
QueryPerformanceFrequency ( & frequency ) ;
# endif
# ifndef PRINT_PICSIZE
get_version ( codec_obj ) ;
# endif
2015-06-09 15:54:31 +05:30
max_op_frm_ts = s_app_ctx . u4_max_frm_ts + s_app_ctx . disp_delay ;
if ( max_op_frm_ts < s_app_ctx . disp_delay )
max_op_frm_ts = 0xffffffff ; /* clip as overflow has occured*/
max_op_frm_ts = ( s_app_ctx . u4_max_frm_ts > 0 ) ? ( max_op_frm_ts ) : 0xffffffff ;
u4_num_disp_bufs_with_dec = 0 ;
2015-03-13 21:24:58 +05:30
while ( u4_op_frm_ts < max_op_frm_ts )
{
# ifdef TEST_FLUSH
if ( u4_ip_frm_ts = = FLUSH_FRM_CNT )
{
ivd_ctl_flush_ip_t s_ctl_ip ;
ivd_ctl_flush_op_t s_ctl_op ;
s_ctl_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_ip . e_sub_cmd = IVD_CMD_CTL_FLUSH ;
s_ctl_ip . u4_size = sizeof ( ivd_ctl_flush_ip_t ) ;
s_ctl_op . u4_size = sizeof ( ivd_ctl_flush_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( ret ! = IV_SUCCESS )
{
printf ( " Error in Setting the decoder in flush mode \n " ) ;
}
// file_pos = 0;
// fseek(ps_ip_file, file_pos, SEEK_SET);
}
# endif
2015-06-09 15:54:31 +05:30
if ( u4_num_disp_bufs_with_dec < s_app_ctx . num_disp_buf )
2015-03-13 21:24:58 +05:30
{
2015-06-09 15:54:31 +05:30
release_disp_frame ( codec_obj , u4_num_disp_bufs_with_dec ) ;
u4_num_disp_bufs_with_dec + + ;
2015-03-13 21:24:58 +05:30
}
/*************************************************************************/
/* set num of cores */
/*************************************************************************/
# ifdef DYNAMIC_NUMCORES
{
ih264d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip ;
ih264d_ctl_set_num_cores_op_t s_ctl_set_cores_op ;
s_ctl_set_cores_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_set_cores_ip . e_sub_cmd = IH264D_CMD_CTL_SET_NUM_CORES ;
s_ctl_set_cores_ip . u4_num_cores = 1 + 3 * ( u4_ip_frm_ts % 2 ) ;
s_ctl_set_cores_ip . u4_size = sizeof ( ih264d_ctl_set_num_cores_ip_t ) ;
s_ctl_set_cores_op . u4_size = sizeof ( ih264d_ctl_set_num_cores_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_set_cores_ip ,
( void * ) & s_ctl_set_cores_op ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str , " \n Error in setting number of cores " ) ;
codec_exit ( ac_error_str ) ;
}
}
# endif
/***********************************************************************/
/* Seek the file to start of current frame, this is equavelent of */
/* having a parcer which tells the start of current frame */
/***********************************************************************/
{
WORD32 numbytes ;
if ( 0 = = s_app_ctx . u4_piclen_flag )
{
fseek ( ps_ip_file , file_pos , SEEK_SET ) ;
numbytes = u4_ip_buf_len ;
}
else
{
WORD32 entries ;
entries = fscanf ( ps_piclen_file , " %d \n " , & numbytes ) ;
if ( 1 ! = entries )
numbytes = u4_ip_buf_len ;
}
u4_bytes_remaining = fread ( pu1_bs_buf , sizeof ( UWORD8 ) ,
numbytes , ps_ip_file ) ;
if ( u4_bytes_remaining = = 0 )
{
if ( 1 = = s_app_ctx . loopback )
{
file_pos = 0 ;
if ( 0 = = s_app_ctx . u4_piclen_flag )
{
fseek ( ps_ip_file , file_pos , SEEK_SET ) ;
numbytes = u4_ip_buf_len ;
}
else
{
WORD32 entries ;
entries = fscanf ( ps_piclen_file , " %d \n " , & numbytes ) ;
if ( 1 ! = entries )
numbytes = u4_ip_buf_len ;
}
u4_bytes_remaining = fread ( pu1_bs_buf , sizeof ( UWORD8 ) ,
numbytes , ps_ip_file ) ;
}
else
break ;
}
}
/*********************************************************************/
/* Following calls can be enabled at diffent times */
/*********************************************************************/
# if ENABLE_DEGRADE
if ( u4_op_frm_ts > = 10000 )
disable_deblocking ( codec_obj , 4 ) ;
if ( u4_op_frm_ts = = 30000 )
enable_deblocking ( codec_obj ) ;
if ( u4_op_frm_ts = = 10000 )
enable_skippb_frames ( codec_obj ) ;
if ( u4_op_frm_ts = = 60000 )
disable_skippb_frames ( codec_obj ) ;
if ( u4_op_frm_ts = = 30000 )
enable_skipb_frames ( codec_obj ) ;
if ( u4_op_frm_ts = = 60000 )
disable_skipb_frames ( codec_obj ) ;
# endif
{
ivd_video_decode_ip_t s_video_decode_ip ;
ivd_video_decode_op_t s_video_decode_op ;
# ifdef PROFILE_ENABLE
UWORD32 s_elapsed_time ;
TIMER s_start_timer ;
TIMER s_end_timer ;
# 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_out_buf - > u4_min_out_buf_size [ 0 ] ;
s_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_out_buf - > u4_min_out_buf_size [ 2 ] ;
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 ] =
ps_out_buf - > pu1_bufs [ 2 ] ;
s_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 ) ;
/* Get display buffer pointers */
if ( 1 = = s_app_ctx . display )
{
WORD32 wr_idx ;
wr_idx = dispq_producer_dequeue ( & s_app_ctx ) ;
if ( s_app_ctx . quit )
break ;
s_app_ctx . set_disp_buffers ( s_app_ctx . pv_disp_ctx , wr_idx ,
& 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 ] ) ;
}
/*****************************************************************************/
/* API Call: Video Decode */
/*****************************************************************************/
GETTIME ( & s_start_timer ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_video_decode_ip ,
( void * ) & s_video_decode_op ) ;
GETTIME ( & s_end_timer ) ;
ELAPSEDTIME ( s_start_timer , s_end_timer , s_elapsed_time , frequency ) ;
# ifdef PROFILE_ENABLE
{
UWORD32 peak_avg , id ;
u4_tot_cycles + = s_elapsed_time ;
peak_window [ peak_window_idx + + ] = s_elapsed_time ;
if ( peak_window_idx = = PEAK_WINDOW_SIZE )
peak_window_idx = 0 ;
peak_avg = 0 ;
for ( id = 0 ; id < PEAK_WINDOW_SIZE ; id + + )
{
peak_avg + = peak_window [ id ] ;
}
peak_avg / = PEAK_WINDOW_SIZE ;
if ( peak_avg > peak_avg_max )
peak_avg_max = peak_avg ;
frm_cnt + + ;
printf ( " FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n " ,
frm_cnt , s_elapsed_time , u4_tot_cycles / frm_cnt , peak_avg_max , s_video_decode_op . u4_output_present , s_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 ;
if ( ! ( frm_cnt % ( s_app_ctx . fps ) ) )
{
time_consumed = time_consumed / s_app_ctx . fps ;
printf ( " Average decode time(micro sec) for the last second = %6d \n " , time_consumed ) ;
printf ( " Average bitrate(kb) for the last second = %6d \n " , ( bytes_consumed * 8 ) / 1024 ) ;
time_consumed = 0 ;
bytes_consumed = 0 ;
}
# endif
# else
printf ( " %d \n " , s_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 ) ;
}
if ( ( IV_SUCCESS ! = ret ) & &
( ( 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 , & s_app_ctx , ps_out_buf ,
pu1_bs_buf , & u4_op_frm_ts ,
ps_op_file , ps_op_chksum_file ,
u4_ip_frm_ts , u4_bytes_remaining ) ;
s_ctl_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_ip . e_sub_cmd = IVD_CMD_CTL_RESET ;
s_ctl_ip . u4_size = sizeof ( ivd_ctl_reset_ip_t ) ;
s_ctl_op . u4_size = sizeof ( ivd_ctl_reset_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_ip ,
( void * ) & s_ctl_op ) ;
if ( IV_SUCCESS ! = ret )
{
sprintf ( ac_error_str , " Error in Reset " ) ;
codec_exit ( ac_error_str ) ;
}
2015-06-09 15:54:31 +05:30
/*when reset all buffers are released by lib*/
u4_num_disp_bufs_with_dec = 0 ;
2015-03-13 21:24:58 +05:30
/*************************************************************************/
/* set num of cores */
/*************************************************************************/
{
ih264d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip ;
ih264d_ctl_set_num_cores_op_t s_ctl_set_cores_op ;
s_ctl_set_cores_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_set_cores_ip . e_sub_cmd = ( IVD_CONTROL_API_COMMAND_TYPE_T ) IH264D_CMD_CTL_SET_NUM_CORES ;
s_ctl_set_cores_ip . u4_num_cores = s_app_ctx . u4_num_cores ;
s_ctl_set_cores_ip . u4_size = sizeof ( ih264d_ctl_set_num_cores_ip_t ) ;
s_ctl_set_cores_op . u4_size = sizeof ( ih264d_ctl_set_num_cores_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_set_cores_ip ,
( void * ) & s_ctl_set_cores_op ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str , " \n Error in setting number of cores " ) ;
codec_exit ( ac_error_str ) ;
}
}
/*************************************************************************/
/* set processsor */
/*************************************************************************/
{
ih264d_ctl_set_processor_ip_t s_ctl_set_num_processor_ip ;
ih264d_ctl_set_processor_op_t s_ctl_set_num_processor_op ;
s_ctl_set_num_processor_ip . e_cmd = IVD_CMD_VIDEO_CTL ;
s_ctl_set_num_processor_ip . e_sub_cmd = ( IVD_CONTROL_API_COMMAND_TYPE_T ) IH264D_CMD_CTL_SET_PROCESSOR ;
s_ctl_set_num_processor_ip . u4_arch = s_app_ctx . e_arch ;
s_ctl_set_num_processor_ip . u4_soc = s_app_ctx . e_soc ;
s_ctl_set_num_processor_ip . u4_size = sizeof ( ih264d_ctl_set_processor_ip_t ) ;
s_ctl_set_num_processor_op . u4_size = sizeof ( ih264d_ctl_set_processor_op_t ) ;
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_ctl_set_num_processor_ip ,
( void * ) & s_ctl_set_num_processor_op ) ;
if ( ret ! = IV_SUCCESS )
{
sprintf ( ac_error_str , " \n Error in setting Processor type " ) ;
codec_exit ( ac_error_str ) ;
}
}
}
if ( ( 1 = = s_app_ctx . display ) & &
( 1 = = s_video_decode_op . u4_output_present ) )
{
dispq_producer_queue ( & s_app_ctx ) ;
}
if ( IV_B_FRAME = = s_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 ;
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 )
{
CHAR cur_fname [ 1000 ] ;
CHAR * extn = NULL ;
/* The objective is to dump the decoded frames into separate files instead of
* dumping all the frames in one common file . Also , the number of dumped frames
* at any given instance of time cannot exceed ' frame_memory '
*/
if ( s_app_ctx . u4_file_save_flag )
{
/* Locate the position of extension yuv */
extn = strstr ( s_app_ctx . ac_op_fname , " %d " ) ;
if ( extn ! = NULL )
{
output_write_stall ( s_app_ctx . ac_op_fname , u4_op_frm_ts ) ;
/* Generate output file names */
sprintf ( cur_fname , s_app_ctx . ac_op_fname , u4_op_frm_ts ) ;
/* Open Output file */
ps_op_file = fopen ( cur_fname , " wb " ) ;
if ( NULL = = ps_op_file )
{
sprintf ( ac_error_str , " Could not open output file %s " ,
cur_fname ) ;
codec_exit ( ac_error_str ) ;
}
}
}
width = s_video_decode_op . s_disp_frm_buf . u4_y_wd ;
height = s_video_decode_op . s_disp_frm_buf . u4_y_ht ;
dump_output ( & s_app_ctx , & ( s_video_decode_op . s_disp_frm_buf ) ,
s_video_decode_op . u4_disp_buf_id , ps_op_file ,
ps_op_chksum_file ,
u4_op_frm_ts , s_app_ctx . u4_file_save_flag ,
s_app_ctx . u4_chksum_save_flag ) ;
u4_op_frm_ts + + ;
if ( extn ! = NULL )
fclose ( ps_op_file ) ;
}
else
{
if ( ( s_video_decode_op . u4_error_code > > IVD_FATALERROR ) & 1 )
{
printf ( " Fatal error \n " ) ;
break ;
}
}
}
}
/***********************************************************************/
/* To get the last decoded frames, call process with NULL input */
/***********************************************************************/
flush_output ( codec_obj , & s_app_ctx , ps_out_buf ,
pu1_bs_buf , & u4_op_frm_ts ,
ps_op_file , ps_op_chksum_file ,
u4_ip_frm_ts , u4_bytes_remaining ) ;
/* set disp_end u4_flag */
s_app_ctx . quit = 1 ;
# ifdef PROFILE_ENABLE
printf ( " Summary \n " ) ;
printf ( " Input filename : %s \n " , s_app_ctx . ac_ip_fname ) ;
printf ( " Output Width : %-4d \n " , width ) ;
printf ( " Output Height : %-4d \n " , height ) ;
if ( frm_cnt )
{
double avg = u4_tot_cycles / frm_cnt ;
double bytes_avg = total_bytes_comsumed / frm_cnt ;
double bitrate = ( bytes_avg * 8 * s_app_ctx . fps ) / 1000000 ;
printf ( " Bitrate @ %2d fps(mbps) : %-6.2f \n " , s_app_ctx . fps , bitrate ) ;
printf ( " Average decode time(micro sec) : %-6d \n " , ( WORD32 ) avg ) ;
printf ( " Avg Peak decode time(%2d frames) : %-6d \n " , PEAK_WINDOW_SIZE , ( WORD32 ) peak_avg_max ) ;
avg = ( u4_tot_cycles + u4_tot_fmt_cycles ) * 1.0 / frm_cnt ;
if ( 0 = = s_app_ctx . u4_share_disp_buf )
printf ( " FPS achieved (with format conv) : %-3.2f \n " , 1000000 / avg ) ;
else
printf ( " FPS achieved : %-3.2f \n " , 1000000 / avg ) ;
}
# endif
/***********************************************************************/
/* Clear the decoder, close all the files, free all the memory */
/***********************************************************************/
if ( 1 = = s_app_ctx . display )
{
s_app_ctx . display_deinit_flag = 1 ;
/* wait for display to finish */
if ( s_app_ctx . display_thread_created )
{
ithread_join ( s_app_ctx . display_thread_handle , NULL ) ;
}
free ( s_app_ctx . display_thread_handle ) ;
}
{
2015-08-04 09:55:15 +05:30
ivd_delete_ip_t s_delete_dec_ip ;
ivd_delete_op_t s_delete_dec_op ;
2015-03-13 21:24:58 +05:30
2015-08-04 09:55:15 +05:30
s_delete_dec_ip . e_cmd = IVD_CMD_DELETE ;
s_delete_dec_ip . u4_size = sizeof ( ivd_delete_ip_t ) ;
s_delete_dec_op . u4_size = sizeof ( ivd_delete_op_t ) ;
2015-03-13 21:24:58 +05:30
2015-08-04 09:55:15 +05:30
ret = ivd_api_function ( ( iv_obj_t * ) codec_obj , ( void * ) & s_delete_dec_ip ,
( void * ) & s_delete_dec_op ) ;
2015-03-13 21:24:58 +05:30
if ( IV_SUCCESS ! = ret )
{
2015-08-04 09:55:15 +05:30
sprintf ( ac_error_str , " Error in Codec delete " ) ;
2015-03-13 21:24:58 +05:30
codec_exit ( ac_error_str ) ;
}
}
/***********************************************************************/
/* Close all the files and free all the memory */
/***********************************************************************/
{
fclose ( ps_ip_file ) ;
if ( ( 1 = = s_app_ctx . u4_file_save_flag ) & & ( strstr ( s_app_ctx . ac_op_fname , " %d " ) = = NULL ) )
{
fclose ( ps_op_file ) ;
}
if ( 1 = = s_app_ctx . u4_chksum_save_flag )
{
fclose ( ps_op_chksum_file ) ;
}
}
if ( 0 = = s_app_ctx . u4_share_disp_buf )
{
free ( ps_out_buf - > pu1_bufs [ 0 ] ) ;
}
for ( i = 0 ; i < s_app_ctx . num_disp_buf ; i + + )
{
free ( s_app_ctx . s_disp_buffers [ i ] . pu1_bufs [ 0 ] ) ;
}
free ( ps_out_buf ) ;
free ( pu1_bs_buf ) ;
2015-09-02 09:01:40 +05:30
if ( s_app_ctx . display_thread_handle )
free ( s_app_ctx . display_thread_handle ) ;
2015-03-13 21:24:58 +05:30
return ( 0 ) ;
}