source: svn/trunk/newcon3bcm2_21bu/dta/src/app/ntia/bapp.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 123.4 KB
Line 
1 /***************************************************************************
2 *     Copyright (c) 2003-2006, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile:  $
11 * $brcm_Revision:  $
12 * $brcm_Date: $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log:  $
19 *
20 ***************************************************************************/
21
22#include "bapp.h"
23#include "bgfx.h"
24#include "bstd.h"
25#include "bos.h"
26#include "ministd.h"
27#include "cache_util.h"
28#include "bapp_palette.h"
29#include "bsettop_graphics.h"
30static void bapp_first_pts_callback(void);
31static void bapp_seq_hdr_callback(void);
32#include "bapp_settings.h"
33#ifdef CONFIG_SCREENSAVER
34#include "logo.c"
35#endif
36#include "psip_descriptor.h"
37#include "bavc.h"               /* dolby logo support */
38
39#ifdef CONFIG_STANDBY
40#include "birw.h"
41#endif
42
43BDBG_MODULE(bapp);              /* Register software module with debug interface */
44
45#define OLD_INFO_KEY_PROCESSING
46
47#define BAPP_MAX_VOLUME                           32
48
49#define BAPP_VCHIP_TIMEOUT            (7000)      /* Milliseconds */
50#define BAPP_RATINGS_EVAL_DELAY       (500)       /* Milliseconds */
51#define BAPP_DIAG_TIMEOUT                               3               /* Seconds */
52#define BAPP_SAVE_TIMEOUT                               3               /* Seconds */
53#define BAPP_RF_TIMEOUT                                 2               /* Seconds */
54
55/* switch to audio only screen timeout check */
56#define BAPP_AUDIO_CHANNEL_SWITCH_TIMEOUT                       5               /* Seconds */
57/* check audio only screen timeout condition if no keypress for given timeout */
58#define BAPP_AUDIO_CHANNEL_KEYPRESS_CHECK_TIMEOUT       2               /* Seconds */
59
60#define BAPP_VCHIP_MSG                                  BDBG_WRN
61#define TIME_APP_DRAWING
62static bgfx_font_t  s_font[eFONT_SIZE_MAX];
63
64static void bapp_eval_state(bapp_t *p_app,bapp_state_t new_state);
65static int bapp_channel_hunt(bapp_t *p_app);
66static void bapp_standby(bapp_t *p_app, bool power);
67static void bapp_new_screen(bapp_t *p_app);
68
69#ifdef CONFIG_8BIT_FONT
70extern unsigned int g_FrancophilB_20_aa_size;
71extern const unsigned char g_FrancophilB_20_aa[];
72extern unsigned int g_FrancophilB_22_aa_size;
73extern const unsigned char g_FrancophilB_22_aa[];
74extern unsigned int g_FrancophilB_28_aa_size;
75extern const unsigned char g_FrancophilB_28_aa[];
76#else
77extern unsigned int g_FrancophilB_22_mono_size;
78extern const unsigned char g_FrancophilB_22_mono[];
79extern unsigned int g_FrancophilB_28_mono_size;
80extern const unsigned char g_FrancophilB_28_mono[];
81extern unsigned int g_FrancophilB_40_mono_size;
82extern const unsigned char g_FrancophilB_40_mono[];
83#endif
84extern int bscreen_eas_text_scrolling_info(bapp_t *p_app, 
85                                                                                   unsigned char *eas_pkt, unsigned int size);
86
87#ifndef NO_VCHIP
88
89#define BAPP_CAD_TIMEOUT        10 /* in seconds */
90
91/* TODO add Mexico rating system support */
92typedef enum rsys_t
93{
94    eRS_MPA,
95    eRS_US,
96    eRS_MPA_OLD,
97    eRS_CANADIAN_ENGLISH,
98    eRS_CANADIAN_FRENCH,
99    eRS_RESERVED_0,
100    eRS_RESERVED_1
101}rsys_t;
102
103const static char *s_rsys_name[] =
104{
105    "MPA",
106    "TV",
107    "MPA",
108    "CE",
109    "CF",
110    "R0",
111    "R1"
112};
113
114/*
115 * Maps value in remote strap registers to bsettop_user_io.c remote type
116 */
117const static unsigned int s_remote_type_map[] =
118{
119        5,
120        4,
121        6,
122        0
123};
124
125#define BAPP_TV_RATING_STR_NUM  8
126static const char *bapp_tv_rating_str[BAPP_TV_RATING_STR_NUM] =
127{
128    "", /* unrated */
129    "TV-Y",
130    "TV-Y7",
131    "TV-G",
132    "TV-PG",
133    "TV-14",
134    "TV-MA",
135    ""  /* unrated */
136};
137
138/* LUT used to translate from user defined tv  limit to canadian equivalent */
139static unsigned char tv_to_can_eng[8] = { 0, 1, 2, 3, 4, 5, 6, 0};
140static unsigned char tv_to_can_fra[8] = { 0, 2, 2, 2, 3, 4, 5, 0};
141
142#define BAPP_MPAA_RATING_STR_NUM    8
143static const char *bapp_mpa_rating_str[] =
144{
145    "", /* unrated */
146    "G",
147    "PG",
148    "PG-13",
149    "R",
150    "NC-17",
151    "X",
152    "NR" /* Not Rated */
153};
154
155#define BAPP_CE_RATING_STR_NUM  8
156static const char *bapp_ce_rating_str[] =
157{
158    "E",
159    "C",
160    "C8+",
161    "G",
162    "PG",
163    "14+",
164    "18+"
165    "", /* invalid */
166};
167
168#define BAPP_CF_RATING_STR_NUM  8
169static const char *bapp_cf_rating_str[] =
170{
171    "E",
172    "G",
173    "8ans+",
174    "13ans+",
175    "16ans+",
176    "18ans+",
177    "", /* invalid */
178    "", /* invalid */
179};
180#endif
181
182/*
183 * Global app reference used by a couple callbacks to reference the application.
184 */
185
186bapp_t *s_p_app = NULL;
187
188static bscreen_t g_screens[] =
189{  /* title_text_id                    desc_text_id                          help_text_id      top_banner_height                               num_buttons                         idle_timeout                          p_button_array                  (* draw)()                     (* handle_event)()             local_state */
190        { eTEXT_MAX,                   eTEXT_MAX,                        eTEXT_MENU_HELP1, 0,                                        0, 0, 0,                              0,          eSCREEN_NULL, 0,                          bscreen_banner_draw,           screen_banner_event,           (uint32_t)&g_banner_state},
191        { eTEXT_MAIN_MENU,             eTEXT_MAX,                        eTEXT_MENU_HELP1, eMENU_TITLE_AREA_HEIGHT_0_LINE,           0, 0, g_buttons_main_num,             SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_main,             bscreen_default_draw,          bscreen_default_event,         0},
192        { eTEXT_PICTURE_MENU,          eTEXT_PICTURE_MENU_DESC,          eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_sd_output_options_config_num,     SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_sd_output_options_config,          bscreen_default_draw,  screen_sd_output_options_config_event,    0},
193        { eTEXT_SOUND_MENU,            eTEXT_SOUND_MENU_DESC,            eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_sound_num,            SCREEN_DEFAULT_TIMEOUT, eSCREEN_AV, g_buttons_sound,            bscreen_default_draw,          screen_sound_event,            0},
194    { eTEXT_AV_MENU,                   eTEXT_AV_MENU_DESC,                   eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_av_num,                   SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_av,                   bscreen_default_draw,          bscreen_default_event,              0},
195        { eTEXT_ANTENNA_MENU,          eTEXT_ANTENNA_MENU_DESC,          eTEXT_MENU_HELP6, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_antenna_draw,          screen_antenna_event,          0},
196    { eTEXT_CAPTIONS_MENU,             eTEXT_CAPTIONS_MENU_DESC,             eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_captions_advanced_num,    SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_advanced,    bscreen_default_draw,          screen_captions_advanced_event,     0},
197        { eTEXT_CAPTIONS_FONT_OPTIONS_MENU,eTEXT_CAPTIONS_FONT_OPTIONS_MENU_DESC,eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_font_options_num,SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_font_options,bscreen_default_draw,          screen_captions_font_options_event, 0},
198    { eTEXT_CAPTIONS_BACK_OPTIONS_MENU,eTEXT_CAPTIONS_BACK_OPTIONS_MENU_DESC,eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_back_options_num,SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_back_options,bscreen_default_draw,          screen_captions_back_options_event, 0},
199    { eTEXT_CAPTIONS_FONT_MENU,        eTEXT_CAPTIONS_FONT_MENU_DESC,        eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_font_num,        SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_font,        bscreen_default_draw,          screen_captions_font_event,         0},
200    { eTEXT_CAPTIONS_FONT_SIZE_MENU,   eTEXT_CAPTIONS_FONT_SIZE_MENU_DESC,   eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_font_size_num,   SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_font_size,   bscreen_default_draw,          screen_captions_font_size_event,    0},
201    { eTEXT_CAPTIONS_FONT_STYLE_MENU,  eTEXT_CAPTIONS_FONT_STYLE_MENU_DESC,  eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_font_style_num,  SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_font_style,  bscreen_default_draw,          screen_captions_font_style_event,   0},
202    { eTEXT_CAPTIONS_FONT_COLOR_MENU,  eTEXT_CAPTIONS_FONT_COLOR_MENU_DESC,  eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_font_color_num,       SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_font_color,       bscreen_default_draw,          screen_captions_font_color_event,   0},
203    { eTEXT_CAPTIONS_FONT_OPACITY_MENU,eTEXT_CAPTIONS_FONT_OPACITY_MENU_DESC,eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_opacity_num,     SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_font_opacity,bscreen_default_draw,          screen_captions_font_opacity_event, 0},
204    { eTEXT_CAPTIONS_BACK_COLOR_MENU,  eTEXT_CAPTIONS_BACK_COLOR_MENU_DESC,  eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_color_num,       SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_color,       bscreen_default_draw,          screen_captions_back_color_event,   0},
205    { eTEXT_CAPTIONS_BACK_OPACITY_MENU,eTEXT_CAPTIONS_BACK_OPACITY_MENU_DESC,eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_opacity_num,     SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_back_opacity,bscreen_default_draw,          screen_captions_back_opacity_event, 0},
206    { eTEXT_CAPTIONS_EDGE_COLOR_MENU  ,eTEXT_CAPTIONS_EDGE_COLOR_MENU_DESC,  eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_edge_color_num,       SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_edge_color,       bscreen_default_draw,          screen_captions_edge_color_event,   0},
207    { eTEXT_CAPTIONS_EDGE_TYPE_MENU   ,eTEXT_CAPTIONS_EDGE_TYPE_MENU_DESC,   eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_edge_type_num,   SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_edge_type,   bscreen_default_draw,          screen_captions_edge_type_event,    0},
208    { eTEXT_CAPTIONS_RESET_MENU,       eTEXT_CAPTIONS_RESET_MENU_DESC,       eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_reset_num,       SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_reset,       bscreen_default_draw,          screen_captions_reset_event,        0},
209        { eTEXT_LANGUAGE_MENU,         eTEXT_LANGUAGE_MENU_DESC,         eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_language_num,         SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_language,         bscreen_default_draw,          screen_language_event,         0},
210#ifdef CONFIG_EIA_708
211        { eTEXT_SETUP_MENU,            eTEXT_SETUP_MENU_DESC,            eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE-4,           0, 0, g_buttons_setup_num,            SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_setup,            bscreen_default_draw,          screen_setup_event,            0},
212#else   
213        { eTEXT_SETUP_MENU,            eTEXT_SETUP_MENU_DESC,            eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_setup_num,            SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_setup,            bscreen_default_draw,          screen_setup_event,            0},
214#endif
215        { eTEXT_WIZ_CH_SCAN_MENU,          eTEXT_WIZ_CH_SCAN_MENU_DESC,          eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_3_LINE,           0, 0, g_buttons_ch_scan_num,              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ch_scan,              bscreen_wiz_ch_scan_draw,      screen_ch_scan_event,          0},
216        { eTEXT_CH_SCAN_PROGRESS_MENU, eTEXT_CH_SCAN_PROGRESS_MENU_DESC, eTEXT_MENU_HELP4, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_ch_scan_progress_draw, screen_ch_scan_progress_event, 0},
217        { eTEXT_RESET_MENU,            eTEXT_RESET_MENU_DESC,            eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_reset_num,            SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_reset,            bscreen_default_draw,          screen_reset_event,            0},
218        { eTEXT_WIZ_WELCOME_MENU,      eTEXT_WIZ_WELCOME_MENU_DESC,      eTEXT_MENU_HELP3, eMENU_TITLE_AREA_HEIGHT_3_LINE,           0, 0, g_buttons_wiz_welcome_num,      SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wiz_welcome,      bscreen_wiz_welcome_draw,      screen_wiz_welcome_event,      0},
219    { eTEXT_WIZ_LANGUAGE_MENU,         eTEXT_LANGUAGE_MENU_DESC,             eTEXT_MENU_HELP8, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_wiz_language_num,         SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wiz_language,         bscreen_default_draw,          screen_wiz_language_event,          0},
220        { eTEXT_WIZ_CH_SCAN_MENU,      eTEXT_WIZ_CH_SCAN_MENU_DESC,      eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_3_LINE,           0, 0, g_buttons_wiz_ch_scan_num,      SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wiz_ch_scan,      bscreen_wiz_ch_scan_draw,      screen_wiz_ch_scan_event,      0},
221        { eTEXT_WIZ_PIN_NEW_MENU,          eTEXT_WIZ_PIN_NEW_MENU_DESC,          eTEXT_MENU_HELP7, eMENU_TITLE_AREA_HEIGHT_4_LINE,           0, 0, 0,                                  SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                              bscreen_pin_draw,              screen_pin_event,              0},
222        { eTEXT_PIN_CONFIRM_MENU,          eTEXT_PIN_CONFIRM_MENU_DESC,          eTEXT_MENU_HELP7, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                                  SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                              bscreen_pin_draw,              screen_pin_event,              0},
223        { eTEXT_MISMATCHED_PINS_MENU,      eTEXT_MISMATCHED_PINS_MENU_DESC,      eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_wiz_mismatched_pins_num,  SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wiz_mismatched_pins,  bscreen_default_draw,          screen_wrong_pin_event,        0},
224        { eTEXT_WIZ_DONE_MENU,         eTEXT_WIZ_DONE_MENU_DESC,         eTEXT_MENU_HELP6, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_wiz_done_num,         SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wiz_done,         bscreen_wiz_done_draw,         screen_wiz_done_event,         0},
225        { eTEXT_AUTO_POWER_MENU,           eTEXT_AUTO_POWER_MENU_DESC,           eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_auto_power_num,           SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_auto_power,           bscreen_auto_power_draw,       screen_auto_power_event,       0},
226        { eTEXT_RATINGS_MENU,          eTEXT_RATINGS_MENU_DESC,          eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_ratings_num,          SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings,          bscreen_default_draw,          screen_ratings_event,          0},
227        { eTEXT_RATINGS_LOCK_MENU,     eTEXT_RATINGS_LOCK_MENU_DESC,     eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_ratings_lock_num,     SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings_lock,     bscreen_default_draw,          screen_ratings_lock_event,     0},
228        { eTEXT_RATINGS_LIMITS_MENU,   eTEXT_RATINGS_LIMITS_MENU_DESC,   eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_ratings_limits_num,   SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings_limits,   bscreen_default_draw,          screen_ratings_limits_event,   0},
229        { eTEXT_RATINGS_TV_MENU,           eTEXT_RATINGS_TV_MENU_DESC,           eTEXT_MENU_HELP2,eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_ratings_tv_num,           SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings_tv,           bscreen_default_draw,          screen_ratings_tv_event,          0},
230        { eTEXT_RATINGS_MOVIES_MENU,   eTEXT_RATINGS_MOVIES_MENU_DESC,   eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_ratings_movies_num,   SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings_movies,   bscreen_default_draw,          screen_ratings_movies_event,   0},
231        { eTEXT_RATINGS_RRT_DIM_MENU,      eTEXT_RATINGS_RRT_DIM_MENU_DESC,      eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, MAX_RRT_DIM_BUTTONS,                SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings_rrt_dim,      bscreen_rrt_dim_draw,          screen_ratings_rrt_dim_event,     0},
232        { eTEXT_RATINGS_RRT_VAL_MENU,      eTEXT_RATINGS_RRT_VAL_MENU_DESC,      eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, MAX_RRT_VAL_BUTTONS,                SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings_rrt_val,      bscreen_rrt_val_draw,          screen_ratings_rrt_val_event,     0},
233        { eTEXT_RATINGS_RRT_UPDATE_MENU,   eTEXT_RATINGS_RRT_UPDATE_MENU_DESC,   eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_ratings_rrt_update_num,   SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_ratings_rrt_update,   bscreen_default_draw,          screen_ratings_rrt_update_event,  0},
234        { eTEXT_PIN_ENTER_MENU,        eTEXT_PIN_ENTER_MENU_DESC,        eTEXT_MENU_HELP9, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_pin_draw,              screen_pin_event,              0},
235        { eTEXT_PIN_ENTER_MENU,        eTEXT_PIN_ENTER_MENU_DESC,        eTEXT_MENU_HELP7, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_pin_draw,              screen_pin_event,              0},
236        { eTEXT_PIN_ENTER_MENU,            eTEXT_PIN_ENTER_MENU_DESC,            eTEXT_MENU_HELP7, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                                  SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                              bscreen_pin_draw,              screen_pin_event,              0},
237        { eTEXT_PIN_NEW_MENU,          eTEXT_PIN_NEW_MENU_DESC,          eTEXT_MENU_HELP7, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_pin_draw,              screen_pin_event,              0},
238        { eTEXT_PIN_CONFIRM_MENU,      eTEXT_PIN_CONFIRM_MENU_DESC,      eTEXT_MENU_HELP7, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_pin_draw,              screen_pin_event,              0},
239        { eTEXT_WRONG_PIN_LIVE_MENU,   eTEXT_WRONG_PIN_LIVE_MENU_DESC,   eTEXT_MENU_HELP8, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_wrong_pin_live_num,   SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wrong_pin_live,   bscreen_default_draw,          screen_wrong_pin_event,        0},
240        { eTEXT_WRONG_PIN_MENU_MENU,       eTEXT_WRONG_PIN_MENU_MENU_DESC,       eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_wrong_pin_ratings_num,    SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wrong_pin_ratings,    bscreen_default_draw,          screen_wrong_pin_event,        0},
241        { eTEXT_WRONG_PIN_MENU_MENU,       eTEXT_WRONG_PIN_MENU_MENU_DESC,       eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_wrong_pin_reset_num,      SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wrong_pin_reset,      bscreen_default_draw,          screen_wrong_pin_event,        0},
242        { eTEXT_MISMATCHED_PINS_MENU,  eTEXT_MISMATCHED_PINS_MENU_DESC,  eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_mismatched_pins_num,  SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_mismatched_pins,  bscreen_default_draw,          screen_wrong_pin_event,        0},
243        { eTEXT_MAX,                   eTEXT_MAX,                        eTEXT_MAX,        0,                                        0, 0, 0,                              BANNER_SMALL_TIMEOUT,   eSCREEN_NULL, 0,                          bscreen_banner_draw,           screen_banner_event,           (uint32_t)&g_banner_state},
244    { eTEXT_GUIDE_TITLE,               eTEXT_MAX,                            eTEXT_MENU_HELP5,eMENU_TITLE_AREA_HEIGHT_0_LINE,           0, 0, 0,                                  SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                              bscreen_guide_draw,            screen_guide_event,                 (uint32_t)&g_guide_state},
245        { eTEXT_MAX,                   eTEXT_MAX,                        eTEXT_MAX,        0,                                        0, 0, 0,                              0,                      eSCREEN_NULL, 0,                          bscreen_screensaver_draw,      screen_screensaver_event,      (uint32_t)&g_screensaver_state},
246        { eTEXT_MAX,                   eTEXT_MAX,                        eTEXT_MAX,        0,                                        0, 0, 0,                              0,                      eSCREEN_NULL, 0,                          bscreen_power_off_draw,        screen_power_off_event,        0},
247        { eTEXT_TIMEZONE_MENU,         eTEXT_TIMEZONE_MENU_DESC,         eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_timezone_num,         SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_timezone,         bscreen_default_draw,          bscreen_timezone_event,        0},
248        { eTEXT_MAX,            /* status */
249                eTEXT_MAX,   
250                eTEXT_MAX,       
251                0,                                       
252                0, 
253                0, 
254                0,                             
255                SCREEN_DEFAULT_TIMEOUT, 
256                eSCREEN_NULL, 
257                0,                         
258                bscreen_status_draw,           
259                bscreen_status_event,         
260                0
261        },
262        { eTEXT_MAX,            /* diag */
263                eTEXT_MAX, 
264                eTEXT_MAX,           
265                0,                     
266                0, 
267                0, 
268                0,     
269                SCREEN_DEFAULT_TIMEOUT, 
270                eSCREEN_MAX, 
271                0,                         
272                bscreen_diag_menu_draw,       
273                bscreen_diag_menu_event,
274                0
275        },
276        { eTEXT_MAX,            /* sys info */
277                eTEXT_MAX,                       
278                eTEXT_MAX,           
279                0,                     
280                0, 
281                0, 
282                0,     
283                SCREEN_DEFAULT_TIMEOUT, 
284                eSCREEN_MAX, 
285                0,                         
286                bscreen_sys_info_draw,         
287                bscreen_sys_info_event,       
288                0
289        },
290        { eTEXT_MAX,            /* tuner status */
291                eTEXT_MAX,
292                eTEXT_MAX,
293                0,
294                0, 
295                0, 
296                0,     
297                SCREEN_DEFAULT_TIMEOUT, 
298                eSCREEN_MAX, 
299                0,
300                bscreen_tuner_status_draw,     
301                bscreen_tuner_status_event,   
302                0
303        },
304        { eTEXT_MAX,            /* channel status */
305                eTEXT_MAX,
306                eTEXT_MAX,
307                0,
308                0, 
309                0, 
310                0,
311                SCREEN_DEFAULT_TIMEOUT, 
312                eSCREEN_MAX, 
313                0,
314                bscreen_ch_status_draw,
315                bscreen_ch_status_event,
316                0
317        },
318        { eTEXT_MAX,            /* decoder status */
319                eTEXT_MAX,
320                eTEXT_MAX, 
321                0,
322                0, 
323                0, 
324                0,
325                SCREEN_DEFAULT_TIMEOUT,
326                eSCREEN_MAX,
327                0, 
328                bscreen_decoder_status_draw,
329                bscreen_decoder_status_event, 
330                0
331        },
332        { eTEXT_SD_CONFIG_OPTIONS_BUTTON,       /* SD output options */
333                eTEXT_SD_CONFIG_OPTIONS, 
334                eTEXT_MENU_HELP2, 
335                eMENU_TITLE_AREA_HEIGHT_1_LINE, 
336                0, 
337                0, 
338                g_buttons_sd_output_options_config_num,
339                SCREEN_DEFAULT_TIMEOUT, 
340                eSCREEN_PICTURE, 
341                g_buttons_sd_output_options_config, 
342                bscreen_default_draw, 
343                screen_sd_output_options_config_event, 
344                0
345        },
346        { eTEXT_RFM_CONFIG_OPTIONS,             /* RFM */
347                eTEXT_RFM_CONFIG_OPTIONS_DESC, 
348                eTEXT_MENU_HELP2, 
349                eMENU_TITLE_AREA_HEIGHT_1_LINE,     
350                0, 
351                0, 
352                g_buttons_rfm_num,
353                SCREEN_DEFAULT_TIMEOUT, 
354                eSCREEN_AV, 
355                g_buttons_rfm, 
356                bscreen_default_draw,
357                screen_rfm_event, 
358                0
359        },
360#ifdef CONFIG_FACTORY_TEST
361        { eTEXT_MAX,
362                eTEXT_MAX,
363                eTEXT_MAX,
364                0,
365                0,
366                0,
367                0,
368                SCREEN_DEFAULT_TIMEOUT, 
369                eSCREEN_MAX, 
370                0,
371                factory_draw,
372                factory_handle_event,
373                0
374        },
375#endif
376        { eTEXT_CAPTIONS_DIGITAL,       /* digital captioning */
377                eTEXT_CAPTIONS_DIGITAL_DESC, 
378                eTEXT_MENU_HELP2, 
379                eMENU_TITLE_AREA_HEIGHT_1_LINE, 
380                0, 
381                0, 
382                g_buttons_captions_digital_num, 
383                SCREEN_DEFAULT_TIMEOUT, 
384                eSCREEN_CAPTIONS_ADVANCED, 
385                g_buttons_captions_digital, 
386                bscreen_default_draw, 
387                screen_digital_captioning_event, 
388                0
389        },
390        { eTEXT_TIMEZONE_MENU,         
391                eTEXT_TIMEZONE_MENU_DESC,         
392                eTEXT_MENU_HELP2, 
393                eMENU_TITLE_AREA_HEIGHT_1_LINE,
394                0, 
395                0, 
396                g_buttons_timezone_num,
397                SCREEN_DEFAULT_TIMEOUT, 
398                eSCREEN_NULL, 
399                g_buttons_timezone,         
400                bscreen_default_draw,         
401                bscreen_wiz_timezone_event,
402                0
403        },
404    { eTEXT_DETAILED_GUIDE,
405                eTEXT_MAX,
406                eTEXT_MENU_HELP10,
407                eMENU_TITLE_AREA_HEIGHT_0_LINE,
408                0, 
409                0, 
410                0,
411                SCREEN_DEFAULT_TIMEOUT,
412                eSCREEN_NULL, 
413                0,
414                bscreen_detailed_guide_draw, 
415                screen_detailed_guide_event,
416                (uint32_t)&g_detailed_guide_state
417        },
418    { eTEXT_MAX,        /* frequency configure */
419        eTEXT_MAX,
420        eTEXT_MAX,
421        0,
422        0,
423        0,
424        0,
425        SCREEN_DEFAULT_TIMEOUT,
426        eSCREEN_MAX,
427        0,
428        bscreen_frequency_draw,
429        screen_frequency_event,
430        0
431    },
432        /* support for Music Channel draw */
433        { eTEXT_MAX,                   
434                eTEXT_MAX,
435                eTEXT_MAX,       
436                0,     
437                0, 
438                0, 
439                0,
440                0,
441                eSCREEN_NULL, 
442                0,
443                bscreen_audio_channel_draw,     
444                screen_audio_channel_event,
445                0
446        },
447};                                                                                                                                                                 
448
449const unsigned char g_screens_num = sizeof(g_screens)/sizeof(g_screens[0]);
450
451void bl_write(void)
452{
453}
454static bgfx_io_t s_io =
455{
456        bin_read,
457        bin_tell,
458        bin_set
459};
460
461
462#if defined(CONFIG_GFX_ARGB32) && !defined(SIMULATOR)
463static bgfx_hw_t s_gfx_hw = {(BGFX_HW_FILL)bsurface_fill, (BGFX_HW_BLIT)bsurface_blit_surface, (BGFX_HW_SURFACE_CREATE)bsurface_create_surface};
464static bgfx_hw_t *s_p_gfx_hw = &s_gfx_hw;
465#else
466static bgfx_hw_t *s_p_gfx_hw = NULL;
467#endif
468
469//#ifdef BCM_DEBUG
470#if 0
471static const char *s_chm_evt_str[] =
472{
473        "CHM_EVT_CANCEL",
474        "CHM_EVT_DONE",
475        "CHM_EVT_REDRAW",
476        "CHM_EVT_PROGRESS",
477        "CHM_EVT_SIGNAL",
478        "CHM_EVT_EAS",
479        "CHM_EVT_STATUS",
480        "CHM_EVT_AV_MUTE",     
481        "CHM_EVT_SAVE",
482        "CHM_EVT_TIME",
483        "eCHM_EVT_RRT",
484        "eCHM_EVT_CAD",
485        "eCHM_EVT_BLOCK",
486        "eCHM_EVT_SET_SCREEN",
487        "eCHM_EVT_SNR",
488        "eCHM_EVT_RESET",
489        "eCHM_EVT_MAX",
490};
491#endif
492
493
494#ifdef ACB612   
495void aov_setAVL_target()
496{
497        int target, lowbound, fixedboost;
498        bapp_get_avl_settings(&target, &lowbound, &fixedboost);
499        target = -11;
500        bapp_set_avl_settings(target, lowbound, fixedboost);
501        return;
502}
503#endif
504/*
505Summary:
506        set video related configuration if default are not match
507 */
508void bapp_set_video_configuration(bapp_t *p_app)
509{
510    bdisplay_settings s;
511
512    bdisplay_get(p_app->display,&s);
513    if (s.sd_options != p_app->settings.sd_options) {
514        s.sd_options = p_app->settings.sd_options;
515        bdisplay_set(p_app->display,&s);
516    }
517}
518
519/*
520Summary:
521        Set the LED mode based on the state and settings.
522*/
523void bapp_led_set_mode(bapp_t *p_app)
524{
525        enum led_mode_t mode = led_off_mode;
526
527        if (!p_app->power)
528        {
529                mode = led_off_mode;
530        } else
531        {
532                switch (p_app->state)
533                {
534                case eAPP_STATE_HUNT:  mode = led_hunt_mode; break;
535                case eAPP_STATE_NORMAL:  mode = led_on_mode;  break;
536                case eAPP_STATE_FACTORY:
537                case eAPP_STATE_DEFAULT:
538                case eAPP_STATE_DONE:
539                        break;
540                }
541        }
542
543        if (mode == p_app->led_mode)
544        {
545                return;
546        }
547
548        p_app->led_mode = mode;
549        led_set_mode(mode);
550}
551
552/*
553 * Flush cache
554 */
555
556void bapp_flush_screen(bapp_t *p_app)
557{
558#ifndef CONFIG_GFX_ARGB32
559        unsigned int *palette;
560        int width,height,pitch;
561#endif
562        if (p_app->settings.av_mute && (p_app->screen_id != eSCREEN_POWER_OFF))
563        {
564                BDBG_WRN(("%s av_mute = %d, screen = %d\n",__FUNCTION__,p_app->settings.av_mute,p_app->screen_id ));
565                return;
566        }
567
568        if (bgraphics_sync(p_app->graphics, false) == berr_timeout)
569        {
570                BDBG_WRN(("bgraphics_sync timeout, try again.\n" ));
571                if (bgraphics_sync(p_app->graphics, false) == berr_timeout)
572                {
573                        BDBG_ERR(("bgraphics_sync timeouted out again.\n" ));
574                }
575        }
576#ifndef CONFIG_GFX_ARGB32
577        bgraphics_get_framebuffer(p_app->graphics,(void**)&p_app->osd_mem,(unsigned int **)&palette,&width,&height,&pitch);
578        p_app->osd_mem_size = pitch * height;
579        p_app->width = width;
580        p_app->height = height;
581        p_app->surf.surface.buf = p_app->osd_mem;
582#endif
583}
584
585/*
586 *  flush SD or HD or both graphics
587 */
588void bapp_flush_screen_partial(bapp_t *p_app, int id)
589{
590#ifdef CONFIG_GFX_ARGB32
591        if (bgraphics_sync_partial(p_app->graphics, id, false) == berr_timeout) {
592                BDBG_WRN(("bgraphics_sync_hd timeout, try again"));
593                if (bgraphics_sync_partial(p_app->graphics, id, false) == berr_timeout) {
594                        BDBG_ERR(("bgraphics_sync timeout again."));
595                }
596        }
597#else
598        bapp_flush_screen(p_app);
599#endif
600}
601
602#ifndef NO_VCHIP
603/*
604 *  Determine ratings system
605 */
606static rsys_t bapp_get_rsys(unsigned char c1, unsigned char c2)
607{
608        if ((c1 & 0x18) == 0x18) /* eRS_CANADIAN_ENGLISH - eRS_RESERVED_1 */
609        {
610                if (c1 & 0x20) /* eRS_CANADIAN_FRENCH or eRS_RESERVED_1 */
611                {
612                        if (c2 & 0x08)
613                                return eRS_RESERVED_1;
614                        else
615                                return eRS_CANADIAN_FRENCH;
616                } else
617                {
618                        if (c2 & 0x08)
619                                return eRS_RESERVED_0;
620                        else
621                                return eRS_CANADIAN_ENGLISH;
622                }
623        } else /* eRS_MPA - eRS_MPA_OLD */
624        {
625                if (c1 & 0x10)
626                        return eRS_MPA_OLD;
627                else if (c1 & 0x08)
628                        return eRS_US;
629                else
630                        return eRS_MPA;
631        }
632        return eRS_US;
633}
634
635/*
636 *  Return 1 if MPA rating is exceeded
637 *  Return 0 if MPA rating is not exceeded
638 *  Return -1 on invalid rating or error
639 */
640static int bapp_mpa_block(
641        unsigned char mpa_level,     /* MPA level 0 - 7 */
642    unsigned char c1             /* xds 1 character */
643    )
644{
645    c1 &= 0x7;
646
647    /* update rating string */
648    if (c1 < BAPP_MPAA_RATING_STR_NUM)
649        strcpy(s_p_app->prog_rating_str, bapp_mpa_rating_str[c1]);
650
651    if (c1 == 0)
652        return -1; /* level 0 rating not applicable */
653
654    return(c1 >= mpa_level) ? 1 : 0;
655}
656
657/*
658 *  Return 1 if Canadian English rating is exceeded
659 *  Return 0 if MPA rating is not exceeded
660 *  Return -1 on invalid rating or error
661 */
662static int bapp_CE_block(
663        unsigned char CE_level,   /* Canadian English level 0 - 7 */
664    unsigned char c2          /* xds 2 character */
665    )
666{
667    c2 &= 0x7;
668    if (c2 == 7)
669        return -1; /* level 7 rating is invalid */
670
671    /* update rating string */
672    if (c2 < BAPP_CE_RATING_STR_NUM)
673        strcpy(s_p_app->prog_rating_str, bapp_ce_rating_str[c2]);
674
675    if (c2 == 0)
676        return -1;
677    return(c2 >= CE_level) ? 1 : 0;
678}
679
680/*
681 * Return 1 if Canadian French rating is exceeded
682 * Return 0 if MPA rating is not exceeded
683 * Return -1 on invalid rating or error
684 */ 
685static int bapp_CF_block(
686        unsigned char CF_level,   /* Canadian French level 0 - 7 */
687        unsigned char c2          /* xds 2 character */
688    )
689{
690    c2 &= 0x7;
691    if ((c2 == 6) || (c2 == 7))
692        return -1; /* level 6 or 7 rating is invalid */
693
694    /* update rating string */
695    if (c2 < BAPP_CF_RATING_STR_NUM)
696        strcpy(s_p_app->prog_rating_str, bapp_cf_rating_str[c2]);
697
698    if (c2 == 0)
699        return -1;
700
701    return(c2 >= CF_level) ? 1 : 0;
702}
703
704/*
705 *  Return 1 if US rating is exceeded
706 *  Return 0 if MPA rating is not exceeded
707 *  Return -1 on invalid rating or error
708 */
709static int bapp_US_block(
710        unsigned char US_level,                 /* US level 0 - 7 */
711        unsigned char mask,             /* VSLD modifier mask */
712        unsigned char c1,               /* xds 1 character */
713        unsigned char c2                /* xds 2 character */
714        )
715{
716    unsigned char tmp_c2 = c2 & 0x7;
717    unsigned char c1_mask,c2_mask;
718    int slen;
719
720    c2_mask = (mask & 0xE) << 2;
721    c1_mask = (mask & 0x1) << 5;
722
723    /* update rating string */
724    if (tmp_c2 < BAPP_TV_RATING_STR_NUM)
725        strcpy(s_p_app->prog_rating_str, bapp_tv_rating_str[tmp_c2]);
726    else
727        s_p_app->prog_rating_str[0] = 0;
728
729    switch (tmp_c2)
730    {
731    case 2:
732        if (c2 & 0x20)
733        {
734            slen = strlen(s_p_app->prog_rating_str);
735            s_p_app->prog_rating_str[slen] = 'F';
736            s_p_app->prog_rating_str[slen + 1] = 'V';
737            s_p_app->prog_rating_str[slen + 2] = 0;
738        }
739        break;
740    case 4:
741    case 5:
742    case 6:
743        if (c2 & 0x20)
744        {
745            slen = strlen(s_p_app->prog_rating_str);
746            s_p_app->prog_rating_str[slen] = 'V';
747            s_p_app->prog_rating_str[slen + 1] = 0;
748        }
749        if (c2 & 0x08)
750        {
751            slen = strlen(s_p_app->prog_rating_str);
752            s_p_app->prog_rating_str[slen] = 'L';
753            s_p_app->prog_rating_str[slen + 1] = 0;
754        }
755        if (c2 & 0x10)
756        {
757            slen = strlen(s_p_app->prog_rating_str);
758            s_p_app->prog_rating_str[slen] = 'S';
759            s_p_app->prog_rating_str[slen + 1] = 0;
760        }
761        if (tmp_c2 != 6)
762        {
763            if (c1 & 0x20)
764            {
765                slen = strlen(s_p_app->prog_rating_str);
766                s_p_app->prog_rating_str[slen] = 'D';
767                s_p_app->prog_rating_str[slen + 1] = 0;
768            }
769        }
770        break;
771    default:
772        break;
773    }
774
775    BDBG_MSG(("Level - %d, LIMIT - %d, mask = 0x%02x(c1m 0x%02x, c2m 0x%02x)\n",tmp_c2,US_level,mask,c1_mask,c2_mask ));
776
777    if ((tmp_c2 == 0) || (tmp_c2 == 0x7))
778        return -1; /* level 0 and 7 ratings not applicable */
779
780    switch (US_level)
781    {
782    case 0:
783        return 0;
784    case 3:
785    case 1:return(tmp_c2 > US_level) ? 1 : 0;
786    case 2:
787        {
788            if (tmp_c2 > US_level)
789                return 1;
790            else
791                if ((tmp_c2 == US_level) && /* handle case where xds rating has no vsld modifier */
792                    ((s_p_app->settings.ratings.ratings_tv >> screen_ratings_tv_xds2pos(US_level)) & (0 | (0x1))))
793                return 1;
794            else
795                if ((tmp_c2 == US_level) && (c2 & (0x20 & c1_mask))) /* FV restriction */
796                return 1;
797        }
798        break;
799    case 4:
800    case 5:
801        {
802            if (tmp_c2 > US_level)
803                return 1;
804            else
805                if ((tmp_c2 == US_level) && /* handle case where xds rating has no vsld modifier */
806                    ((s_p_app->settings.ratings.ratings_tv >> screen_ratings_tv_xds2pos(US_level)) & (0 | (0x1))))
807                return 1;
808            else
809                if ((tmp_c2 == US_level) &&
810                    ((c2 & (0x38 & c2_mask)) || (c1 & (0x20 & c1_mask)))) /* VSLD restriction */
811                return 1;
812        }
813        break;
814    case 6:
815        {
816            if (tmp_c2 > US_level)
817                return 1;
818            else
819                if ((tmp_c2 == US_level) && /* handle case where xds rating has no vsld modifier */
820                    ((s_p_app->settings.ratings.ratings_tv >> screen_ratings_tv_xds2pos(US_level)) & (0 | (0x1))))
821                return 1;
822            else
823                if ((tmp_c2 == US_level) && (c2 & (0x38 & c2_mask))) /* VSL restriction */
824                return 1;
825        }
826        break;
827    }
828    return 0;
829}
830
831/*
832 * Return 1 if rating is enabled and exceeded
833 * Return 0 if rating is disabled or not exceeded
834 * Returns -1 on invalid rating or error
835 */
836static int bapp_block(
837        bapp_t *p_app,
838        unsigned char c1,               /* xds 1 character */
839        unsigned char c2                /* xds 2 character */
840    )
841{
842        rsys_t rsys;
843        unsigned char mask    = 0;
844        int           blocked = 0;
845
846        rsys = bapp_get_rsys(c1,c2);
847
848        BAPP_VCHIP_MSG(("%s-0x%02x,0x%02x\n",s_rsys_name[rsys],c1,c2));
849
850        switch (rsys)
851        {
852                default:
853                case eRS_MPA_OLD:
854                case eRS_MPA:
855                        {
856                                unsigned char rat    = 0;
857
858                                /* determine most restrictive user selected movie rating and convert to xds equivalent. */
859                                if ((p_app->settings.ratings.ratings_movies >> 0) & (0 | (0x1)))
860                                        rat = 1;
861                                else
862                                        if ((p_app->settings.ratings.ratings_movies >> 1) & (0 | (0x1)))
863                                                rat = 2;
864                                        else
865                                                if ((p_app->settings.ratings.ratings_movies >> 2) & (0 | (0x1)))
866                                                        rat = 3;
867                                                else
868                                                        if ((p_app->settings.ratings.ratings_movies >> 3) & (0 | (0x1)))
869                                                                rat = 4;
870                                                        else
871                                                                if ((p_app->settings.ratings.ratings_movies >> 4) & (0 | (0x1)))
872                                                                        rat = 5;
873                                                                else
874                                                                        if ((p_app->settings.ratings.ratings_movies >> 5) & (0 | (0x1)))
875                                                                                rat = 6;
876                                                                        else
877                                                                                if ((p_app->settings.ratings.ratings_movies >> 6) & (0 | (0x1)))
878                                                                                        rat = 7;
879                                                                                else
880                                                                                        rat = 0;
881
882                                BAPP_VCHIP_MSG(("@@@ ratings_movie:%x rat:%d\n", p_app->settings.ratings.ratings_movies, rat));
883                                blocked = bapp_mpa_block(rat, c1);
884                                break;
885                        }
886                case eRS_US:
887                        {
888                                unsigned char tmp_c2 = c2 & 0x7;
889                                unsigned char d      = 0;
890                                unsigned char l      = 0;
891                                unsigned char s      = 0;
892                                unsigned char v      = 0;
893                                unsigned char fv     = 0;
894                                unsigned char rat    = 0;
895
896                                switch (tmp_c2)
897                                {
898                                        case 1:
899                                                mask = 0;
900                                                break;
901                                        case 2:
902                                                /* build tv-y7 content ratings mask */
903                                                fv = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_Y7_FV) & (0 | (0x1)));
904                                                mask = (fv << 3);
905                                                break;
906                                        case 3:
907                                                mask = 0;
908                                                break;
909                                        case 4:
910                                                /* build tv-pg and tv-14 content ratings mask */
911                                                d = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_PG_D) & (0 | (0x1)));
912                                                l = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_PG_L) & (0 | (0x1)));
913                                                s = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_PG_S) & (0 | (0x1)));
914                                                v = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_PG_V) & (0 | (0x1)));
915                                                mask = ((v << 3) | (s << 2) | (l << 1) | (d << 0));
916                                                break;
917                                        case 5:
918                                                d = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_14_D) & (0 | (0x1)));
919                                                l = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_14_L) & (0 | (0x1)));
920                                                s = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_14_S) & (0 | (0x1)));
921                                                v = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_14_V) & (0 | (0x1)));
922                                                mask = ((v << 3) | (s << 2) | (l << 1) | (d << 0));
923                                                break;
924                                        case 6:
925                                                /* build tv-ma content ratings mask */
926                                                d = 0;
927                                                l = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_MA_L) & (0 | (0x1)));
928                                                s = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_MA_S) & (0 | (0x1)));
929                                                v = ((p_app->settings.ratings.ratings_tv >> ePOS_TV_MA_V) & (0 | (0x1)));
930                                                mask = ((v << 3) | (s << 2) | (l << 1) | (d << 0));
931                                                break;
932                                        default:
933                                                mask = 0;
934                                                break;
935                                }
936
937                                /* determine most restrictive user selected tv rating and convert to xds equivalent. */
938                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_Y) & (0 | (0x1)))
939                                        rat = 1;
940                                else
941                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_Y7) & (0 | (0x3)))
942                                                rat = 2;
943                                        else
944                                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_G) & (0 | (0x1)))
945                                                        rat = 3;
946                                                else
947                                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_PG) & (0 | (0x1F)))
948                                                                rat = 4;
949                                                        else
950                                                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_14) & (0 | (0x1F)))
951                                                                        rat = 5;
952                                                                else
953                                                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_MA) & (0 | (0x1F)))
954                                                                                rat = 6;
955                                                                        else
956                                                                                rat = 0;
957
958                                BAPP_VCHIP_MSG(("@@@ ratings_tv:%x rat:%d\n", p_app->settings.ratings.ratings_tv, rat));
959                                blocked = bapp_US_block(rat,mask,c1,c2);
960                        }
961                        break;
962
963                case eRS_CANADIAN_ENGLISH:
964                        {
965                                unsigned char rat = 0;
966
967                                /* determine most restrictive user selected tv rating and convert to xds equivalent. */
968                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_Y) & (0 | (0x1)))
969                                        rat = 1;
970                                else
971                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_Y7) & (0 | (0x3)))
972                                                rat = 2;
973                                        else
974                                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_G) & (0 | (0x1)))
975                                                        rat = 3;
976                                                else
977                                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_PG) & (0 | (0x1F)))
978                                                                rat = 4;
979                                                        else
980                                                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_14) & (0 | (0x1F)))
981                                                                        rat = 5;
982                                                                else
983                                                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_MA) & (0 | (0x1F)))
984                                                                                rat = 6;
985                                                                        else
986                                                                                rat = 0;
987
988                                blocked = bapp_CE_block(tv_to_can_eng[rat], c2);
989                        }
990                        break;
991
992                case eRS_CANADIAN_FRENCH:
993                        {
994                                unsigned char rat = 0;
995
996                                /* determine most restrictive user selected tv rating and convert to xds equivalent. */
997                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_Y) & (0 | (0x1)))
998                                        rat = 1;
999                                else
1000                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_Y7) & (0 | (0x3)))
1001                                                rat = 2;
1002                                        else
1003                                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_G) & (0 | (0x1)))
1004                                                        rat = 3;
1005                                                else
1006                                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_PG) & (0 | (0x1F)))
1007                                                                rat = 4;
1008                                                        else
1009                                                                if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_14) & (0 | (0x1F)))
1010                                                                        rat = 5;
1011                                                                else
1012                                                                        if ((p_app->settings.ratings.ratings_tv >> ePOS_TV_MA) & (0 | (0x1F)))
1013                                                                                rat = 6;
1014                                                                        else
1015                                                                                rat = 0;
1016
1017                                blocked = bapp_CF_block(tv_to_can_fra[rat], c2);
1018                        }
1019                        break;
1020        }
1021
1022        /* we go thru ratings evaluation so we can always display current rating whether we are currently enforcing it or not */
1023        if (p_app->settings.ratings.ratings_lock == 0)
1024                blocked = 0;
1025
1026        BDBG_MSG(("%s:%d (%d %s)\n", __FUNCTION__,__LINE__,blocked,p_app->prog_rating_str));
1027        {
1028                static chm_event_t rating_evt;
1029                rating_evt.type = eCHM_EVT_REDRAW;
1030                rating_evt.id = blocked;
1031                rating_evt.ticks = bos_getticks();
1032                bos_post_event(p_app->msg_queue, (b_event_t *)&rating_evt);
1033        }
1034
1035        return blocked;
1036}
1037
1038/*
1039 * Callback to process XDS data (V-CHIP)
1040 */
1041static void  bapp_xds_callback(
1042        int xds_class,                  /* the class (0 - current, used for vchip) */
1043        int xds_type,           /* the xds type (5 - vchip) */
1044        unsigned char* data,    /* the data buffer, containing data_len valid bytes */
1045        int data_len            /* the number of valid bytes in data */
1046        )
1047{
1048    if (data_len != 2)
1049        return;
1050
1051    if (xds_class == 0)
1052    {
1053        /* Current class */
1054        if (xds_type == 5)
1055        {
1056            static chm_event_t chm_evt;
1057            int block = 0;
1058            b_timeval tv;
1059            unsigned int current_ticks = bos_getticks();
1060
1061            /* ignore rating if ratings was received while tuned to a different channel. */
1062            if (current_ticks < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
1063                return;
1064
1065            GETTIMEOFDAY(&tv);
1066            s_p_app->last_xds = tv.tv_sec;
1067
1068            /* VCHIP processing */
1069            block = bapp_block(s_p_app,data[0],data[1]);
1070            BDBG_WRN(("bapp_block(0x%02x,0x%02x) - %d, 0x%08x\n",data[0],data[1],block,current_ticks));
1071
1072            if (block != -1)
1073            {
1074                s_p_app->last_rating_tick = current_ticks;
1075
1076                if (block != s_p_app->last_rating_block_status)
1077                {
1078                    chm_evt.type = eCHM_EVT_BLOCK;
1079                    chm_evt.id = block;
1080                    chm_evt.ticks = current_ticks;
1081                    bos_post_event(s_p_app->msg_queue,(b_event_t*)&chm_evt);
1082                }
1083                s_p_app->last_rating_block_status = block;
1084            }
1085        }
1086    } else if (xds_class == 3)
1087    {
1088        /* Miscellaneous class */
1089        if (xds_type == 1)
1090        {
1091            /* time of day */
1092        } else if (xds_type == 4)
1093        {
1094#if 0 /* JPF XDS time is unreliable in current BA broadcasts */
1095            /* local time zone */
1096            BDBG_WRN(("### UTC OFFSET = %d(s) ###\n", data[0] & 0x1F,(data[0] & 0x20) ? "DST" : "STD"));
1097            g_xds_time_offset = data[0] & 0x1F;
1098            g_xds_dst = (data[0] & 0x20) ? 1 : 0;
1099#endif
1100        }
1101    }
1102}
1103#endif
1104
1105/*
1106Summary:
1107Set volume level
1108Description:
1109Set Volume level (range 0(full) - s_volume_num)
1110*/
1111void bapp_set_audio_volume(bapp_t *p_app, uint8_t level)
1112{
1113        baudio_decode_config config;
1114
1115        if (p_app->system_mute)
1116                return;
1117
1118        if (level == p_app->audio_vol) return;
1119
1120        if (level > BAPP_MAX_VOLUME) 
1121                level = BAPP_MAX_VOLUME;
1122
1123        baudio_decode_get_config(p_app->audio, &config);
1124        config.left_volume = config.right_volume = level;
1125        baudio_decode_set_config(p_app->audio, &config);
1126        p_app->audio_vol = level;
1127        p_app->settings_dirty |= DIRTY_CHANNEL;/*janzy@20121101,save and apply audio_volume*/
1128}
1129
1130/*
1131Summary:
1132Mute audio
1133Description:
1134Mute audio when enable is non-zero.
1135*/
1136void bapp_audio_mute(bapp_t *p_app, int mute)
1137{
1138        baudio_decode_config config;
1139
1140        if (p_app->system_mute)
1141                return;
1142
1143        if ((mute && p_app->is_muted) || (!mute && !p_app->is_muted) || p_app->settings.av_mute || (p_app->audio_mute && p_app->is_muted))
1144                return;
1145
1146        baudio_decode_get_config(p_app->audio, &config);
1147        config.mute = (mute == 0) ? false : true;
1148        if (baudio_decode_set_config(p_app->audio, &config) != b_ok)
1149        {
1150                BDBG_WRN(("%s baudio_decode_set_config mute = %d failed\n",__FUNCTION__,config.mute));
1151        }
1152        else
1153                p_app->is_muted = mute;
1154}
1155
1156/*janzy@20121108,add DolbyDrc mode function*/
1157void bapp_audio_SetDolbyDrc_mode(bapp_t *p_app, baudio_dolby_drc_mode mode)
1158{
1159        baudio_decode_config config;
1160
1161       
1162        baudio_decode_get_config(p_app->audio, &config);
1163        config.dolby.drc_mode = mode;
1164
1165        if (baudio_decode_set_config(p_app->audio, &config) != b_ok)
1166        {
1167                BDBG_WRN(("%s baudio_decode_set_config mute = %d failed\n",__FUNCTION__,config.dolby.drc_mode));
1168        }
1169        return;
1170}
1171
1172/*janzy@20121108,add DolbyDrc mode function*/
1173void bapp_audio_GetDolbyDrc_mode(bapp_t *p_app, baudio_dolby_drc_mode mode)
1174{
1175        baudio_decode_config config;
1176
1177       
1178        baudio_decode_get_config(p_app->audio, &config);
1179       
1180        mode = config.dolby.drc_mode;
1181
1182        return;
1183}
1184
1185
1186/*
1187Summary:
1188Mute video
1189Description:
1190Mute video only
1191*/
1192void bapp_video_mute(bapp_t *p_app, int mute)
1193{
1194        bdecode_config cfg;
1195
1196        bdecode_get_config(p_app->decode,&cfg);
1197        if (mute)
1198                cfg.mute = 1;
1199        else
1200                cfg.mute = 0;
1201
1202        bdecode_set_config(p_app->decode,&cfg);
1203}
1204
1205/*
1206Summary:
1207Mute both audio and video.
1208Description:
1209Mute both audio and video when enable is non-zero.
1210*/
1211void bapp_av_mute(bapp_t *p_app, int mute)
1212{
1213        bapp_audio_mute(p_app,mute);
1214        bapp_video_mute(p_app,mute);
1215
1216        if (mute)
1217        {
1218                bapp_sync(p_app);
1219                bgfx_fill_rect(&p_app->surf,0,0,eWIDTH,eHEIGHT,eCOLOR_CLEAR);
1220                bapp_flush_screen(p_app);
1221        }
1222
1223        /* 'reset' feature will invoke setup wizard. it shouldn't mute graphics. see screen_reset_event */
1224        p_app->settings.av_mute = (mute==1)?mute:0;
1225        p_app->settings_dirty |= DIRTY_MISC;
1226}
1227/*
1228Summary:
1229Configure the video output mode.
1230Description:
1231Configure the video output mode.
1232*/
1233void bapp_output_mode(bapp_t *p_app, int widescreen)
1234{
1235#if 0 /* JPF TODO SET OUTPUT MODE- extend to HD */
1236        bdecode_config cfg;
1237        bdecode_get_config(p_app->decode,&cfg);
1238        if (widescreen)
1239        {
1240                BDBG_WRN(("Widescreen (%d)\n", widescreen));
1241                cfg.widescreen = widescreen;
1242        } else
1243        {
1244                BDBG_WRN(("Full Screen...\n"));
1245                cfg.widescreen = 0;
1246        }
1247        bdecode_set_config(p_app->decode,&cfg);
1248#endif
1249}
1250
1251/*
1252Summary:
1253Apply the current settings.
1254Description:
1255Apply the current settings. Restart decode.
1256*/
1257static void bapp_apply_settings(bapp_t *p_app)
1258{
1259        p_app->audio_vol  = p_app->settings.audio_vol;
1260        bapp_set_audio_volume(p_app, p_app->audio_vol);
1261}
1262
1263#ifdef HAS_HDMI
1264/*
1265Summary:
1266        Reset the Video output to the default values.
1267*/
1268void bapp_reset_hd_config_settings(bapp_t *p_app)
1269{
1270        p_app->settings.hd_config.output_format = bdisplay_format_auto;
1271        p_app->settings.hd_config.hd_options = bdisplay_hd_output_options_auto;
1272        p_app->settings.hd_config.sharpness = 0; /* soft */
1273
1274}
1275#endif
1276
1277/*
1278Summary:
1279        Reset the closed captioning settings to the default values.
1280*/
1281void bapp_reset_cc_config_settings(bapp_t *p_app)
1282{
1283       
1284#ifdef CONFIG_EIA_708
1285        p_app->captions_basic = 0;
1286    p_app->settings.dcc.captions_basic = 0;                     /* disable digital captioning */
1287    p_app->settings.dcc.captions_font = 0;                      /* auto */
1288    p_app->settings.dcc.captions_font_size = 0;         /* auto */
1289    p_app->settings.dcc.captions_font_style = 0;        /* normal */
1290    p_app->settings.dcc.captions_font_color = 0;        /* default */
1291    p_app->settings.dcc.captions_font_opacity = 0;
1292    p_app->settings.dcc.captions_back_color  = 0;
1293    p_app->settings.dcc.captions_back_opacity = 0;
1294    p_app->settings.dcc.captions_edge_color = 0;
1295    p_app->settings.dcc.captions_edge_type = 0;
1296    p_app->settings.dcc.captions_analog = 1;            /* disable analog captioning */
1297    p_app->settings.dcc.captions_digital = 0;           /* we use captions_basic instead this variable for CSx switch */
1298
1299        p_app->settings_dirty |= DIRTY_DCC;
1300#endif
1301}
1302
1303/*
1304Summary:
1305Reset the current user settings
1306Description:
1307Reset the current user settings.  Note this does not change them in flash.
1308*/
1309void bapp_reset_settings(bapp_t *p_app)
1310{
1311        memset(&p_app->settings, 0, sizeof(p_app->settings));
1312        bdisplay_settings s;
1313
1314        //ch_map_init(&(p_app->settings.ch_map),&(p_app->ch_map_mutex));
1315        /* this will make sure volume is reset to default from UI */
1316        p_app->audio_mute = false;              //audio mute release
1317        p_app->settings.audio_vol = BAPP_MAX_VOLUME;
1318        p_app->audio_vol = BAPP_MAX_VOLUME;
1319        p_app->settings.rrt_settings.pin = DEFAULT_PIN;
1320        p_app->settings.psi_scan = 1;
1321#ifdef ACB612/*janzy@20121115,fixed factory function(Key 9) to reset default*/
1322        p_app->settings.wiz_completed = 0;
1323#else
1324        p_app->settings.wiz_completed = 1;
1325#endif
1326#ifdef ACB612
1327        p_app->settings.language = eLANG_SPANISH;       
1328#endif
1329#ifdef HAS_HDMI
1330        bapp_reset_hd_config_settings(p_app);
1331#endif
1332        //widescreen default AR / bscreen /
1333        p_app->settings.sd_options = bdisplay_sd_output_options_widescreen;
1334        s.sd_options = bdisplay_sd_output_options_widescreen;
1335        bdisplay_set(p_app->display,&s);
1336        /* need to reset it for consistency of DCC option */
1337        p_app->captions_basic = 0;
1338        //alternate audio default
1339        p_app->settings.sound = 1;
1340        p_app->settings.dcc.captions_analog = 1;
1341        p_app->settings.rfm=0;
1342        p_app->settings.dst=0;  //When STB reset,daylight init.
1343        p_app->chm.local_dst_obs = p_app->settings.dst;
1344        brfm_set_ch3(p_app->p_rfm, p_app->settings.rfm);
1345
1346
1347
1348}
1349
1350/*
1351Summary:
1352Load current settings from NVM
1353*/
1354static void bapp_load_settings(bapp_t *p_app)
1355{
1356        int result = 0;
1357
1358        memset(&p_app->settings.ch, 0, sizeof(p_app->settings.ch));
1359        p_app->settings_dirty = 0;
1360
1361        if (bos_acquire_mutex(&p_app->ch_map_mutex, 45) == b_ok)
1362        {
1363                if (bos_acquire_mutex(&(s_p_app->flash_mutex), 250) == b_ok)
1364                {
1365                        result = bast_channel_read(p_app);
1366                        if (0 == result || 3 == result)
1367                        {
1368                                result = bast_misc_read(p_app);
1369                                if (0 == result || 3 == result) {
1370                                        result = bast_channel_map_read(p_app);
1371                                        if (0 == result || 3 == result)
1372                                        {
1373                                                result = bast_screen_read(p_app);
1374                                                if (0 == result)
1375                                                {
1376                                                        result = bast_eas_read(p_app);
1377                                                }
1378                                        }
1379                                        else {
1380                                                p_app->settings.num_channels = p_app->cur_ch_num = 0;
1381                                        }
1382                                }
1383                        }
1384                        bos_release_mutex(&(s_p_app->flash_mutex));
1385                }
1386                else 
1387                {
1388                        BDBG_WRN(("%s:%d mutex timeout", __FUNCTION__, __LINE__));
1389                }
1390
1391                bos_release_mutex(&p_app->ch_map_mutex);
1392                if (0 == result) 
1393                {
1394                        //ch_output(bapp_cur_ch_map(p_app));
1395                }
1396                else
1397                {
1398                        BDBG_WRN(("Error loading settings, resetting to default."));
1399
1400                        bapp_reset_settings(p_app);
1401                        p_app->audio_vol = p_app->settings.audio_vol;
1402                        p_app->settings_dirty = DIRTY_CHANNEL | DIRTY_MISC | DIRTY_EAS | 
1403                                DIRTY_CHANNEL_MAP | DIRTY_SCREEN;
1404                        bapp_save_settings(p_app);
1405
1406                }
1407        }
1408        return; 
1409}
1410
1411/*
1412Summary:
1413Save current settings to NVM
1414Description:
1415Save current settings to NVM
1416*/
1417void bapp_save_settings(bapp_t *p_app)
1418{
1419        if (bos_acquire_mutex(&(s_p_app->flash_mutex), 250) != b_ok) 
1420        {
1421                BDBG_WRN(("%s:%d mutex timeout\n", __FUNCTION__, __LINE__));
1422                return;
1423        }
1424
1425        if (0 != (p_app->settings_dirty & DIRTY_CHANNEL))
1426        {
1427                /* update unsaved settings */
1428                p_app->settings.audio_vol = p_app->audio_vol;
1429                bast_channel_save(p_app);
1430                p_app->settings_dirty &= ~DIRTY_CHANNEL;
1431        }
1432
1433        /* use MISC instead of having its own DB */
1434        if (p_app->settings_dirty & DIRTY_HD_CONFIG) {
1435                bdisplay_settings s;
1436                bdisplay_get(p_app->display,&s);
1437#ifdef HAS_HDMI
1438                p_app->settings.hd_config.output_format = s.format;
1439                p_app->settings.hd_config.hd_options = s.hd_options;
1440                p_app->settings.hd_config.sharpness = s.sharpness;
1441                p_app->settings_dirty &= ~DIRTY_HD_CONFIG;
1442#endif
1443                p_app->settings.sd_options = s.sd_options;
1444                p_app->settings_dirty |= DIRTY_MISC;
1445        }
1446
1447        if (p_app->settings_dirty & DIRTY_DEBUG_CONFIG) {
1448                p_app->settings_dirty &= ~DIRTY_DEBUG_CONFIG;
1449                p_app->settings_dirty |= DIRTY_MISC;
1450        }
1451
1452        if (0 != (p_app->settings_dirty & DIRTY_MISC))
1453        {
1454                bast_misc_save(p_app);
1455                p_app->settings_dirty &= ~DIRTY_MISC;
1456        }
1457
1458        if (0 != (p_app->settings_dirty & DIRTY_EAS))
1459        {
1460                bast_eas_save(p_app);
1461                p_app->settings_dirty &= ~DIRTY_EAS;
1462        }
1463
1464        if (0 != (p_app->settings_dirty & DIRTY_SCREEN))
1465        {
1466                bast_screen_save(p_app);
1467                p_app->settings_dirty &= ~DIRTY_SCREEN;
1468        }
1469
1470        if (bos_acquire_mutex(&p_app->ch_map_mutex,45) == b_ok)
1471        {
1472                if (0 != (p_app->settings_dirty & DIRTY_CHANNEL_MAP))
1473                {
1474                        bast_channel_map_save(p_app);
1475                        p_app->settings_dirty &= ~DIRTY_CHANNEL_MAP;
1476                }
1477                bos_release_mutex(&p_app->ch_map_mutex);
1478        }
1479        else 
1480        {
1481                BDBG_WRN(("%s:%d mutex timeout", __FUNCTION__, __LINE__));
1482        }
1483        bos_release_mutex(&(s_p_app->flash_mutex));
1484}
1485/*
1486Summary:
1487Power down audio DAC and power off
1488*/
1489void bapp_do_poweroff(bapp_t *p_app)
1490{
1491        bapp_standby(p_app, false);
1492}
1493
1494/*
1495Summary:
1496Initialize the main app structure.
1497Description:
1498Do necessary configuration of main app structure.  Assumes
1499p_app is allocated and p_surf and palette are initialized.
1500*/
1501void bapp_init(bapp_t *p_app)
1502{
1503
1504        bapp_lang_t e_lang;
1505        bgraphics_settings graphics_settings;
1506        bresult rc;
1507        unsigned int *palette;  /* [out] address of palette */
1508        int width;                              /* [out] width of the OSD surface  */
1509        int height;                             /* [out] height of the OSD surface  */
1510        int pitch;                              /* [out] pitch of the OSD surface  */
1511        bdecode_config cfg;
1512        #ifdef ACB612
1513        static int ntimeout;
1514        int ngetkey;
1515        #endif
1516        bool isBootUpFromPowerPlugIn = false;
1517       
1518        BDBG_MSG(("%s:%d\n",__FUNCTION__,__LINE__));
1519
1520
1521        #if(AOV_MODEL == ALCO)
1522        printf("\nMODEL = ALCO\n");
1523        #elif (AOV_MODEL == ZINWELL)
1524        printf("\nMODEL = ZINWELL\n");
1525        #else
1526        printf("\nMODEL = %d\n",AOV_MODEL);
1527        #endif
1528
1529        #if(USERIO_ID == 5)
1530        printf("\nRemote = RCA\n");
1531        #elif (USERIO_ID == 4)
1532        printf("\nRemote = ARC-008\n");
1533        #elif (USERIO_ID == 10)
1534        printf("\nRemote = MK-35\n");
1535        #elif (USERIO_ID == 11)
1536        printf("\nRemote = ZRC-4502\n");
1537        #elif(USERIO_ID == 12)/*janzy@20121030,add remote Skyworth_01*/
1538        printf("\nRemote = Skyworth_01\n");
1539        #else
1540        printf("\nRemote = %d\n",USERIO_ID);
1541        #endif
1542
1543
1544
1545        memset(p_app,0,sizeof(bapp_t));
1546
1547        s_p_app = p_app;
1548        p_app->last_key_down = (bIR_codes_t)0xFFF;
1549
1550        p_app->last_screen_id = eSCREEN_MAX;
1551
1552        bsettop_init(0);
1553
1554#ifdef ACB612/*janzy@20121106,enable pass through before entering standby*/
1555#ifdef MERGE_20121115
1556        isBootUpFromPowerPlugIn = ((b_GetKBD1_KBD_PAT0() == 0)?true:false);
1557#endif
1558#endif 
1559
1560        GETTIMEOFDAY(&p_app->timeout_tv);
1561        p_app->user_io = buser_input_open(B_ID(USERIO_ID));
1562        bast_init(p_app);
1563        #ifdef ACB612/*ChengYu@20120809: for XModem firmware upgrade*/
1564        p_app->factory_test = false;
1565        ngetkey = AOV_buser_input_GetButtonfactory();
1566        if(ngetkey== eButton_D00)
1567        {
1568/*RLQ*/
1569void fupdate(void);
1570
1571                fupdate();
1572        }
1573        else if(ngetkey == eButton_0U0)
1574        {
1575                p_app->factory_test = true;
1576/*RLQ*/
1577#if 0
1578                printf("\n\n\n%15s@%5d:%25s Factory Enable\n\n",strrchr(__FILE__,'/')? strrchr(__FILE__,'/')+1 : __FILE__,__LINE__,__FUNCTION__);
1579                printf("\n\n\n%15s@%5d:%25s Factory Enable\n\n",strrchr(__FILE__,'/')? strrchr(__FILE__,'/')+1 : __FILE__,__LINE__,__FUNCTION__);
1580                printf("\n\n\n%15s@%5d:%25s Factory Enable\n\n",strrchr(__FILE__,'/')? strrchr(__FILE__,'/')+1 : __FILE__,__LINE__,__FUNCTION__);
1581#endif
1582        }
1583        #endif 
1584
1585        bgraphics_get(&graphics_settings);
1586        graphics_settings.format = bgraphics_pixel_format_palette4;
1587        bgraphics_set(&graphics_settings);
1588
1589        if(!isBootUpFromPowerPlugIn)
1590        {
1591                BDBG_WRN(("Open display...\n"));
1592                p_app->display = bdisplay_open(B_ID(0));
1593                BDBG_WRN(("Display opened %d\n",p_app->display));
1594        }
1595
1596        BDBG_WRN(("Open decoder...\n"));
1597        p_app->decode = bdecode_open(0);
1598        BDBG_ASSERT(p_app->decode);
1599
1600        BDBG_WRN(("Decoder opened 0x%08x\n",p_app->decode));
1601
1602        smessage_init(NULL);
1603
1604        if(!isBootUpFromPowerPlugIn)
1605        {
1606                p_app->window[0] = bdecode_window_open(0, p_app->display);
1607        p_app->window[1] = bdecode_window_open(1, p_app->display);
1608        }
1609
1610       
1611        p_app->audio = baudio_decode_open(B_ID(0));
1612        if (!p_app->audio)
1613        {
1614                BDBG_WRN(("baudio_decode_open failed\n"));
1615        }
1616        p_app->audio_mute = 0;
1617
1618#if HAS_HDMI
1619        rc = bsettop_hdmi_open(&(p_app->hdmi),p_app->display,p_app->audio, NULL /* no hdcp authentication callback needed*/);
1620        BDBG_ASSERT(rc == b_ok);
1621#endif
1622
1623#if (BCHP_VER>=BCHP_VER_B0)
1624        p_app->p_rfm = brfm_open(0);
1625#endif
1626
1627        if(!isBootUpFromPowerPlugIn)
1628        {
1629                /* turn on green LED */
1630        buser_AOV_input_LED(p_app->p_rfm, eLED_Status_G);
1631        }
1632       
1633        bos_create_queue(&p_app->msg_queue, p_app->msg_event, MAX_MSG_EVENT);
1634        BDBG_ASSERT(p_app->msg_queue);
1635
1636        rc = bos_create_mutex(&p_app->ch_map_mutex);
1637        BDBG_ASSERT(rc == b_ok);
1638
1639        rc = bos_create_mutex(&p_app->flash_mutex);
1640        BDBG_ASSERT(rc == b_ok);
1641
1642        //ch_map_init(&(p_app->settings.ch_map),&(p_app->ch_map_mutex));
1643#ifdef CONFIG_SCREENSAVER
1644        p_app->logo = (unsigned char *)s_logo;
1645        p_app->logo_size = s_logo_size;
1646#endif
1647
1648#ifdef DOLBY_LOGO_NO_D
1649/* defined in dolby_logo_no_D.c */
1650extern unsigned int g_dolby_logo_no_D_size;
1651extern const unsigned char g_dolby_logo_no_D[];
1652        /* dolby logo to show in the banner screen */
1653        p_app->dolby_logo = (unsigned char *)g_dolby_logo_no_D;
1654        p_app->dolby_logo_size = g_dolby_logo_no_D_size;
1655#else
1656extern unsigned int g_dolby_logo_240_size;
1657extern const unsigned char g_dolby_logo_240[];
1658
1659        /* dolby logo to show in the banner screen */
1660        p_app->dolby_logo = (unsigned char *)g_dolby_logo_240;
1661        p_app->dolby_logo_size = g_dolby_logo_240_size;
1662#endif
1663//12-02 splash screen added
1664extern unsigned int g_dst_logoSize;
1665extern const unsigned char g_dst_logo[];
1666        p_app->dst_logo = (unsigned char *)g_dst_logo;
1667        p_app->dst_logoSize = g_dst_logoSize;
1668
1669        if(!isBootUpFromPowerPlugIn)
1670        {
1671                p_app->graphics = bgraphics_open(B_ID(0),p_app->display);
1672        }
1673
1674        /* should after bgraphics_open, since bgraphics_open will overwrite some BVN TOP registers, e.g. AMOL */
1675        chm_init(&p_app->chm,p_app);
1676
1677
1678        /*janzy@20121106,enable pass through before entering standby*/
1679        if(isBootUpFromPowerPlugIn)
1680        {
1681                BDBG_ERR(("######## Turn OFF ########\n"));
1682#ifdef CONFIG_NXP_TDA182I4
1683#ifdef MERGE_20121115
1684                NXP_TDA182I4_SetLoopThrough(true);/*janzy@20121108,add NXP_TDA182I4_SetLoopThrough*/
1685#endif
1686                NXP_TDA182I4_SetStandby();
1687#endif
1688#ifdef CONFIG_STANDBY
1689                bos_sleep(200);
1690                b_s3_standby(USERIO_ID);
1691#endif
1692                p_app->power = false;
1693                while(1)
1694                {
1695                        bos_sleep(200);
1696                }
1697        }
1698       
1699        p_app->yield_ms = APP_DEFAULT_YIELD;
1700        p_app->lang = eLANG_ENGLISH;
1701
1702        bgraphics_get_framebuffer(p_app->graphics,(void**)&p_app->osd_mem,(unsigned int **)&palette,&width,&height,&pitch);
1703        bapp_set_palette(p_app,ePALETTE_DEFAULT);
1704        bgraphics_load_palette(p_app->graphics);
1705        p_app->osd_mem_size = pitch * height;
1706        p_app->width = width;
1707        p_app->height = height;
1708        BDBG_MSG(("%s:%d - Width = %d, Height = %d, Pitch = %d.\n",__FUNCTION__,__LINE__,width,height,pitch));
1709
1710        BDBG_MSG(("%s:%d - Initialize screens.\n",__FUNCTION__,__LINE__));
1711
1712        /* Default to NULL (empty) screen (TODO:  goto factory test then setup wizard.) */
1713        p_app->screen_id = eSCREEN_BANNER;
1714
1715        p_app->p_screens = g_screens;
1716        p_app->num_screens = g_screens_num;
1717
1718        BDBG_MSG(("%s:%d - Initialize bgfx.\n",__FUNCTION__,__LINE__));
1719        /* initialize bgfx */
1720        bgfx_init(&s_io,NULL,s_p_gfx_hw);
1721#ifdef CONFIG_GFX_ARGB32
1722        bgraphics_get_osd_params(p_app->graphics,(bsettop_surf_t*)&(p_app->surf.surface.surf),(void**)&(p_app->osd_mem),NULL,NULL);
1723        if (bgfx_create(&p_app->surf,p_app->width,p_app->height,(uint8_t*)p_app->osd_mem, 
1724                                pitch,NULL,BGFX_SURF_BPP(32)|BGFX_SURF_RGB|BGFX_SURF_GRC) != 0)
1725        {
1726                BDBG_ASSERT(0);
1727        }
1728#else
1729        /* Create the OSD surface to use for all drawing */
1730        if (bgfx_create(&p_app->surf,p_app->width,p_app->height,(uint8_t*)p_app->osd_mem,
1731                                pitch,&p_app->palette, BGFX_SURF_PRIMARY | BGFX_SURF_BPP(4)) != 0)
1732        {
1733                BDBG_ASSERT(0);
1734        }
1735#endif
1736
1737        bgfx_fill_rect(&p_app->surf,0,0,p_app->width,p_app->height,eCOLOR_CLEAR);
1738
1739
1740        //----------------------- splash image
1741        p_app->br.cnt = 0;
1742        p_app->br.data = (void*)p_app->dst_logo;
1743        p_app->br.size =  p_app->dst_logoSize;
1744                       
1745        bgfx_render_file(&p_app->surf, 0, 0, &p_app->br, 0);
1746        bapp_flush_screen(p_app);
1747
1748        bos_sleep(3000);
1749       
1750        bgfx_fill_rect(&p_app->surf,0,0,p_app->width,p_app->height,eCOLOR_CLEAR);
1751        //-----------------------
1752
1753        BDBG_MSG(("%s:%d - Load fonts.\n",__FUNCTION__,__LINE__));
1754
1755        memset(&s_font[eFONT_SIZE_SMALL],0,sizeof(bgfx_font_t) * 3);
1756        p_app->br.cnt = 0;
1757#ifdef CONFIG_8BIT_FONT
1758        p_app->br.data = (unsigned char*)g_FrancophilB_20_aa;
1759        p_app->br.size = g_FrancophilB_22_aa_size;
1760#else
1761        p_app->br.data = (unsigned char*)g_FrancophilB_22_mono;
1762        p_app->br.size = g_FrancophilB_22_mono_size;
1763#endif
1764        if (bgfx_load_font(&(s_font[eFONT_SIZE_SMALL]),&p_app->br) != 0)
1765        {
1766                BDBG_ASSERT(0);
1767        }
1768
1769        p_app->br.cnt = 0;
1770#ifdef CONFIG_8BIT_FONT
1771        p_app->br.data = (unsigned char*)g_FrancophilB_22_aa;
1772        p_app->br.size = g_FrancophilB_28_aa_size;
1773#else
1774        p_app->br.data = (unsigned char*)g_FrancophilB_28_mono;
1775        p_app->br.size = g_FrancophilB_28_mono_size;
1776#endif
1777        if (bgfx_load_font(&(s_font[eFONT_SIZE_MED]),&p_app->br) != 0)
1778        {
1779                BDBG_ASSERT(0);
1780        }
1781
1782        p_app->br.cnt = 0;
1783#ifdef CONFIG_8BIT_FONT
1784        p_app->br.data = (unsigned char*)g_FrancophilB_28_aa;
1785        p_app->br.size = g_FrancophilB_28_aa_size;
1786#else
1787        p_app->br.data = (unsigned char*)g_FrancophilB_40_mono;
1788        p_app->br.size = g_FrancophilB_40_mono_size;
1789#endif
1790        if (bgfx_load_font(&(s_font[eFONT_SIZE_LARGE]), &p_app->br) != 0)
1791        {
1792                BDBG_ASSERT(0);
1793        }
1794
1795        for (e_lang = eLANG_ENGLISH; e_lang < eLANG_MAX; ++e_lang)
1796        {
1797                p_app->p_font[e_lang][eFONT_SIZE_SMALL] = &s_font[eFONT_SIZE_SMALL];
1798                p_app->p_font[e_lang][eFONT_SIZE_MED] = &s_font[eFONT_SIZE_MED];
1799                p_app->p_font[e_lang][eFONT_SIZE_LARGE] = &s_font[eFONT_SIZE_LARGE];
1800        }
1801
1802        bapp_load_settings(p_app);
1803        /* set current language */
1804        p_app->lang = p_app->settings.language;
1805        p_app->captions_basic = p_app->settings.dcc.captions_basic;
1806
1807#if (BCHP_VER>=BCHP_VER_B0)
1808        /* if not default CH3, then set to CH4 */
1809        if (p_app->settings.rfm)
1810                brfm_set_ch3(p_app->p_rfm, p_app->settings.rfm);
1811#endif
1812
1813        bapp_set_video_configuration(p_app);
1814#if(AOV_MODEL == ZINWELL)
1815        /* will make AVL configurable */
1816        bapp_P_enable_avl(p_app, false);/*janzy@20121108,Disable AVL*/
1817#else
1818        /* will make AVL configurable */
1819        bapp_P_enable_avl(p_app, false);
1820#endif
1821
1822#ifdef ACB612   
1823        aov_setAVL_target();
1824#endif
1825
1826#ifndef NO_VCHIP
1827    p_app->ratings_override = false;
1828    /* reset so ratings will be re-evaluated when returned to full tv */
1829    p_app->last_rating_block_status = -1;
1830    /* assume psip unblock */
1831    p_app->last_psip_rating_block_status = 0;
1832#endif
1833
1834        bapp_apply_settings(p_app);
1835
1836        BDBG_WRN(("%s:%d - av_mute = %d\n",__FUNCTION__,__LINE__,p_app->settings.av_mute));
1837        BDBG_WRN(("%s:%d - prev_state = %d\n",__FUNCTION__,__LINE__,p_app->settings.state));
1838
1839#ifdef CONFIG_EIA_708
1840        p_app->eia708 = bapp_eia708_open(p_app);
1841        BAPP_ASSERT(p_app->eia708);
1842
1843        bdecode_get_config(p_app->decode, &cfg);
1844        cfg.cc_callback = bapp_eia708_cb;
1845#ifndef NO_VCHIP
1846        cfg.xds_callback = bapp_xds_callback;
1847#endif
1848        bdecode_set_config(p_app->decode, &cfg);
1849#endif
1850
1851#if(AOV_MODEL == ZINWELL)
1852        /*janzy@20121108,set DolbyDrc = baudio_dolby_drc_mode_line*/
1853        bapp_audio_SetDolbyDrc_mode(p_app, baudio_dolby_drc_mode_line);
1854#else
1855        bapp_audio_SetDolbyDrc_mode(p_app, baudio_dolby_drc_mode_rf);
1856#endif
1857
1858        bapp_av_mute(p_app,0);
1859
1860        /*janzy@20121101,save and apply audio_volume begin*/
1861        unsigned char vol_temp;
1862        vol_temp = p_app->settings.audio_vol;
1863        p_app->audio_vol = 0;
1864        bapp_set_audio_volume(p_app, vol_temp);
1865        /*end*/
1866
1867        bapp_flush_screen(p_app);
1868
1869        if (p_app->settings.num_channels > 0) {
1870                bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX);
1871        }
1872        else {
1873                if (!p_app->settings.wiz_completed) { /* first time to run, launch welcome screen */
1874                    memset(&p_app->settings, 0, sizeof(p_app->settings));
1875                        if (0 == p_app->settings.audio_vol) {
1876                                p_app->settings.audio_vol = BAPP_MAX_VOLUME;
1877                                bapp_apply_settings(p_app);
1878                                p_app->audio_vol = BAPP_MAX_VOLUME;
1879                        }
1880                        p_app->settings.rrt_settings.pin = DEFAULT_PIN;
1881#ifdef ACB612
1882                        p_app->settings.language = eLANG_SPANISH;
1883#endif
1884                        bapp_set_current_screen(p_app, eSCREEN_WIZ_WELCOME, eSCREEN_MAX);
1885                } 
1886                else {
1887                        bapp_set_current_screen(p_app, eSCREEN_MAIN, eSCREEN_MAX);
1888                }
1889                p_app->settings.sound = 1;
1890                p_app->settings.sd_options = bdisplay_sd_output_options_widescreen;
1891                p_app->settings.dcc.captions_analog = 1;
1892        }
1893        /* enable CC */
1894        bapp_enable_cc(p_app, true);
1895
1896        bapp_new_screen(p_app);
1897        p_app->power = 1;
1898
1899        /* Always enter pending state on hard power up. */
1900#ifdef  CONFIG_DTA_CABLE_TESTING
1901        p_app->settings.psi_scan = 1;
1902        bapp_eval_state(p_app,eAPP_STATE_NORMAL);
1903#else
1904        p_app->settings.psi_scan = 1;
1905        if (p_app->settings.psi_scan)
1906                bapp_eval_state(p_app,eAPP_STATE_NORMAL);
1907        else
1908                bapp_eval_state(p_app,eAPP_STATE_HUNT);
1909#endif
1910
1911#ifdef ACB612/*janzy@20120803*/
1912        if(p_app->factory_test == true)
1913        {
1914                ntimeout = 0;
1915                bapp_channel_hunt(p_app);
1916                while(!chm_GetScanStatusFinish())
1917                {
1918                        bos_sleep(100);
1919                        ntimeout++;
1920                        if(ntimeout > 1000)
1921                                break;
1922                }
1923                p_app->state = eAPP_STATE_FACTORY;
1924                bapp_set_current_screen(p_app, eSCREEN_STATUS, eSCREEN_MAX);
1925                bapp_new_screen(p_app);
1926        }
1927#endif
1928        /* in case no signal in the bootup */
1929        p_app->last_keypress_tick = bos_getticks();
1930        /* initialize it in case there is no any key press after bootup */
1931        p_app->power_saver_tick = bos_getticks();
1932
1933#ifdef BCM_DEBUG
1934        BDBG_SetModuleLevel("bscreen",BDBG_eWrn);
1935        timing_profile_init();
1936        p_app->ptp_tune = timing_profile_get("Tune");           /* start tune to first pts */
1937        p_app->ptp_psi = timing_profile_get("PSI");             /* profile psi (PAT/PMT) */
1938        p_app->ptp_first_pts = timing_profile_get("PTS");       /* profile start decode to first PTS */
1939        p_app->ptp_decode = timing_profile_get("Decode");       /* start tuner to first pts */
1940        bdecode_get_config(p_app->decode,&cfg);
1941        cfg.first_pts_callback = bapp_first_pts_callback;
1942        cfg.seq_hdr_callback = bapp_seq_hdr_callback;
1943
1944        bdecode_set_config(p_app->decode,&cfg);
1945#endif
1946}
1947/*
1948Summary:
1949Main app event handler.
1950Description:
1951Main application event handler.
1952*/
1953void bapp_handle_event(bapp_t *p_app, bscreen_event_t *p_event)
1954{
1955        if (p_event && (p_event->type == eS_EVENT_IR) && (p_event->id >= eIR_CHMAP))
1956        {
1957                BDBG_WRN(("%s:%d - event_id = 0x%08x",__FUNCTION__,__LINE__,p_event->id));
1958                switch (p_event->id)
1959                {
1960                        case eIR_CHMAP: /* Output channel map on UART */
1961                                //ch_output(bapp_cur_ch_map(p_app));
1962                                break;
1963
1964                        case eIR_SCAN: /* Perform channel scan */
1965                                p_app->state = eAPP_STATE_NORMAL;
1966                                if (p_app->settings.psi_scan)
1967                                {
1968                                }
1969                                bapp_eval_state(p_app,eAPP_STATE_HUNT);
1970                                break;
1971
1972                        case eIR_SETUP: /* Perform default setup */
1973                                p_app->state = eAPP_STATE_NORMAL;
1974                                //bapp_eval_state(p_app,eAPP_STATE_DOWNLOAD);
1975                                BDBG_WRN(("%s:%d - eIR_SETUP\n",__FUNCTION__,__LINE__));
1976                                break;
1977
1978                        case eIR_EXIT: /* Exit to banner menu */
1979                                bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX);
1980                                if (p_app->system_mute) {
1981                                        bapp_audio_do_mute(p_app, false);       
1982                                        bapp_video_mute(p_app, false);
1983                                }
1984                                break;
1985
1986                        default:
1987                                if ((p_event->id & eIR_SETCH) == eIR_SETCH)
1988                                {
1989                                        /* TODO Tune to channel number */
1990                                        bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX);
1991                                }
1992                                break;
1993                }
1994        }
1995}
1996
1997/*
1998Summary:
1999Main app idle time handler.
2000Description:
2001Main application idle time handler.
2002*/
2003
2004void bapp_idle(bapp_t *p_app)
2005{
2006        b_timeval end_tv;
2007        unsigned int delta_hrs;
2008        static b_timeval last_tv = { 0, 0};
2009#ifndef NO_VCHIP
2010        bool   rating_timeout = false;
2011        static chm_event_t chm_evt;
2012    uint32_t current_ticks = bos_getticks();
2013#endif
2014        GETTIMEOFDAY(&end_tv);
2015        /* PVT Monitor */
2016        if (end_tv.tv_sec > (last_tv.tv_sec + 2))
2017        {
2018                bsettop_pvt();
2019                last_tv = end_tv;
2020        }
2021
2022        delta_hrs = (end_tv.tv_sec - p_app->timeout_tv.tv_sec)/(60 * 60);
2023        if ((delta_hrs > 0) && (((int)p_app->settings.timeout_cnt) > 0))
2024        {
2025                p_app->settings.timeout_cnt--;
2026                BDBG_WRN(("%s decriment timeout counter %d\n",__FUNCTION__,p_app->settings.timeout_cnt));
2027                p_app->timeout_tv = end_tv;
2028        }
2029
2030#ifndef NO_VCHIP
2031    /* check if last psip rating has timed out */
2032    if ((p_app->last_cad + BAPP_CAD_TIMEOUT) < end_tv.tv_sec)
2033    {
2034        if (p_app->last_psip_rating_block_status == 1)
2035        {
2036            BDBG_WRN(("clear PSIP rating to unrated - timed out! %d\n",end_tv.tv_sec));
2037            p_app->last_psip_rating_block_status = 0;
2038            /* clear ratings string */
2039            rating_timeout = true;
2040        }
2041        p_app->psip_rating_str[0] = 0;
2042    }
2043
2044    /* check if last xds rating has timed out */
2045    if ((p_app->last_rating_tick + MS_TO_TICKS(BAPP_VCHIP_TIMEOUT)) < current_ticks)
2046    {
2047        if (p_app->last_rating_block_status == 1)
2048        {
2049            BDBG_WRN(("clear XDS rating to unrated - timed out! (0x%08x)\n",current_ticks));
2050            p_app->last_rating_block_status = 0;
2051            /* clear ratings string */
2052            rating_timeout = true;
2053        }
2054        p_app->prog_rating_str[0] = 0;
2055    }
2056
2057    /* send unblock message if both rating types have timed out */
2058    if ((rating_timeout) &&
2059        (p_app->last_rating_block_status != 1) && (p_app->last_psip_rating_block_status != 1))
2060    {
2061        BDBG_WRN(("current rating timed out - unblocking!"));
2062        /* Unblock since a previous rating has timed out */
2063        chm_evt.type = eCHM_EVT_BLOCK;
2064        chm_evt.id = 0;
2065        chm_evt.ticks = current_ticks;
2066        bos_post_event(s_p_app->msg_queue,(b_event_t*)&chm_evt);
2067    }
2068#endif
2069
2070        if (p_app->check_poweron)
2071        {
2072                if (p_app->poweron_ms < bos_getticks())
2073                {
2074                        p_app->check_poweron = false;
2075                }
2076        }
2077    if ((p_app->state == eAPP_STATE_NORMAL) &&
2078        p_app->eas_timeout && (p_app->eas_timeout < end_tv.tv_sec) && p_app->eas_one_iteration)
2079    {
2080        p_app->eas_timeout = 0;
2081        p_app->eas_started = false;
2082        p_app->eas_one_iteration = false;
2083        if (p_app->eas_text || p_app->eas_activation_text)
2084        {
2085            p_app->eas_text = false;
2086            p_app->eas_activation_text = false;
2087            bapp_sync(p_app);
2088            screen_null_draw(p_app, NULL);
2089            bapp_flush_screen(p_app);
2090        }
2091                if (p_app->eas_ch_found)
2092        {
2093            bapp_tune_prev(p_app);
2094            p_app->eas_ch_found = false;
2095        }
2096        bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX);
2097#ifdef CONFIG_EIA_708
2098                bapp_enable_cc(p_app, true);
2099#endif
2100    }
2101
2102#ifdef OLD_INFO_KEY_PROCESSING
2103    if (p_app->last_key_down == eIR_INFO)
2104    {
2105        BDBG_WRN(("%s: p_app->last_key_down == eIR_INFO \n",__FUNCTION__));
2106        b_timeval cur_tv;
2107        GETTIMEOFDAY(&cur_tv);
2108        if ((p_app->last_key_tv.tv_sec + BAPP_DIAG_TIMEOUT) <= cur_tv.tv_sec)
2109        {
2110            BDBG_WRN(("%s: DIAG_TIMEOUT \n",__FUNCTION__));
2111            bapp_set_current_screen(p_app, eSCREEN_DIAG_MENU, eSCREEN_MAX);
2112            bapp_new_screen(p_app);
2113        }
2114    }
2115#endif
2116        if ((p_app->state == eAPP_STATE_NORMAL) && ((p_app->last_save_tv.tv_sec + BAPP_SAVE_TIMEOUT) < end_tv.tv_sec)) {
2117                p_app->last_save_tv = end_tv;
2118                if (p_app->settings_dirty)
2119                        bapp_save_settings(p_app);
2120        }
2121        /* for audio only channel screen draw */
2122        if ((p_app->state == eAPP_STATE_NORMAL) && (0 == p_app->eas_timeout) &&
2123                (0 == p_app->cur_ch.video_pid && p_app->chm.decoding_audio)) 
2124        {
2125                if ((eSCREEN_NULL == p_app->screen_id) || (eSCREEN_BANNER_SMALL == p_app->screen_id)) {
2126                        if ((bos_getticks() - p_app->last_keypress_tick) > MS_TO_TICKS(BAPP_AUDIO_CHANNEL_KEYPRESS_CHECK_TIMEOUT * 1000))
2127                        {
2128                                if ((p_app->audio_channel_tm.tv_sec + BAPP_AUDIO_CHANNEL_SWITCH_TIMEOUT) <= end_tv.tv_sec) {
2129                                        bapp_set_current_screen(p_app, eSCREEN_AUDIO_CHANNEL, p_app->screen_id);
2130                                        bapp_new_screen(p_app);
2131                                }       
2132                        }
2133                        else {
2134                                GETTIMEOFDAY(&p_app->audio_channel_tm);
2135                        }
2136                }       
2137        }
2138}
2139/*
2140Summary:
2141Wait for vsync.
2142Description:
2143Block waiting for vsync so drawing can by syncronized with screen refresh.
2144 */
2145void bapp_sync(bapp_t *p_app)
2146{
2147        /* do nothing */
2148}
2149
2150/*
2151Summary:
2152Enable closed captioning.
2153Description:
2154Enable closed captioning and send clear characters.
2155 */
2156void bapp_enable_cc(bapp_t *p_app, int enable)
2157{
2158#ifdef CONFIG_EIA_708
2159        static bool first = true;
2160        bool changed = false;
2161        bdecode_config cfg;
2162        bool digital = bapp_eia708_enabled(p_app->eia708);
2163
2164        bdecode_get_config(p_app->decode,&cfg);
2165        /* p_app->settings.dcc.captions_digital */
2166        if (p_app->settings.dcc.captions_basic < 1) {
2167                if (cfg.cc_enabled || first) {
2168                        cfg.cc_enabled = false;
2169                        bapp_eia708_enable(p_app->eia708, false);
2170                        changed = true;
2171                }
2172        }
2173        else {
2174                if (digital != enable || first) {
2175                        cfg.cc_enabled = enable;
2176                        bapp_eia708_enable(p_app->eia708, enable);
2177                        changed = true;
2178                }       
2179        }
2180        if (p_app->settings.dcc.captions_analog < 1) {
2181                if (!cfg.block_vbi || first) {
2182                        cfg.block_vbi = true;
2183                        changed = true;
2184                }
2185        }
2186        else {
2187                if (enable == cfg.block_vbi || first) {
2188                        cfg.block_vbi = !enable;
2189                        changed = true;
2190                }
2191        }
2192        if (changed) {
2193                bdecode_set_config(p_app->decode,&cfg);
2194        }
2195        p_app->cc_enabled = enable;
2196        first = false;
2197#endif
2198}
2199/*
2200Summary:
2201Handle new screen.
2202Description:
2203Block waiting for vsync so drawing can by syncronized with screen refresh.
2204 */
2205static void bapp_screen_redraw(bapp_t *p_app)
2206{
2207        bscreen_event_t screen_event;
2208        screen_event.type = eS_EVENT_REDRAW;
2209        screen_event.id = 0;
2210        BDBG_MSG(("%s:%d - sending setup event to %d.\n",__FUNCTION__,__LINE__,p_app->screen_id));
2211        p_app->p_screens[p_app->screen_id].handle_event(p_app,(void*)&(p_app->p_screens[p_app->screen_id]),&screen_event);
2212}
2213
2214/*
2215Summary:
2216Handle new screen.
2217Description:
2218Block waiting for vsync so drawing can by syncronized with screen refresh.
2219 */
2220static void bapp_new_screen(bapp_t *p_app)
2221{
2222        bscreen_event_t screen_event;
2223#ifdef TIME_APP_DRAWING
2224        b_timeval start_tv,end_tv,result_tv;
2225        unsigned int dt;
2226#endif
2227        screen_event.type = 0;
2228        if (p_app->last_screen_id != (int)p_app->screen_id)
2229        {
2230                BDBG_MSG(("%s:%d - sending setup event to %d.\n",__FUNCTION__,__LINE__,p_app->screen_id));
2231                screen_event.type = eS_EVENT_SETUP;
2232                screen_event.id = 0;
2233                p_app->p_screens[p_app->screen_id].handle_event(p_app,(void*)&(p_app->p_screens[p_app->screen_id]),&screen_event);
2234        }
2235
2236        p_app->last_screen_id = p_app->screen_id;
2237#ifdef TIME_APP_DRAWING
2238        GETTIMEOFDAY(&start_tv);
2239#endif
2240
2241        //bapp_sync(p_app);
2242        p_app->p_screens[p_app->screen_id].draw(p_app,(void*)&(p_app->p_screens[p_app->screen_id]));
2243        bapp_flush_screen(p_app);
2244
2245#ifdef TIME_APP_DRAWING
2246        GETTIMEOFDAY(&end_tv);
2247        timeval_subtract(&result_tv,&end_tv,&start_tv);
2248        dt = result_tv.tv_sec * 1000 + result_tv.tv_usec/1000;
2249        BDBG_WRN(("Drawing screen %d took %d ms",p_app->screen_id,dt));
2250#endif
2251
2252        /* send a setup done event to start any post drawing setup */
2253        if (screen_event.type == eS_EVENT_SETUP)
2254        {
2255                screen_event.type = eS_EVENT_SETUP_DONE;
2256                screen_event.id = 0;
2257                if (p_app->p_screens[p_app->screen_id].handle_event(p_app,(void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
2258                {
2259                        p_app->last_screen_id = p_app->screen_id;
2260                        screen_event.type = eS_EVENT_SETUP;
2261                        screen_event.id = 0;
2262                        p_app->p_screens[p_app->screen_id].handle_event(p_app,(void*)&(p_app->p_screens[p_app->screen_id]),&screen_event);
2263#ifdef TIME_APP_DRAWING
2264                        GETTIMEOFDAY(&start_tv);
2265#endif
2266                        //bapp_sync(p_app);
2267                        p_app->p_screens[p_app->screen_id].draw(p_app,(void*)&(p_app->p_screens[p_app->screen_id]));
2268                        bapp_flush_screen(p_app);
2269
2270#ifdef TIME_APP_DRAWING
2271                        GETTIMEOFDAY(&end_tv);
2272                        timeval_subtract(&result_tv,&end_tv,&start_tv);
2273                        dt = result_tv.tv_sec * 1000 + result_tv.tv_usec/1000;
2274                        BDBG_WRN(("Drawing took %d milliseconds\n",dt));
2275#endif
2276                }
2277        }
2278}
2279
2280/*
2281 * Summary:
2282 * Clear screen selection history
2283 * Description:
2284 * Clear screen selection history
2285 *  */
2286void bapp_clear_screen_selection_history(bapp_t *p_app)
2287{
2288        int i;
2289
2290        for (i = 0; i < p_app->num_screens; i++)
2291        {
2292                p_app->p_screens[i].button_selection = 0;
2293        }
2294}
2295
2296/*
2297Summary:
2298sets the current screen for display
2299Description:
2300sets the current screen for display. 
2301if id == eSCREEN_MAX then simply backup a screen
2302if save_last == eSCREEN_MAX, also saves last screen id.
2303 */
2304void bapp_set_current_screen(bapp_t *p_app, bapp_screen_id_t id, bapp_screen_id_t save_last)
2305{
2306        bscreen_t *p_screen     = &(p_app->p_screens[p_app->screen_id]);
2307        bscreen_t *p_screen_new = &(p_app->p_screens[id]);
2308#ifdef BCM_DEBUG
2309        unsigned int cur_screen = p_app->screen_id;
2310#endif
2311        BDBG_WRN(("Attempt to change screen from %d to %d\n",cur_screen, id));
2312
2313        if (id == p_app->screen_id)
2314                return;
2315
2316        if (id == eSCREEN_MAX)
2317        {
2318                bapp_goto_last_screen(p_app);
2319        } else
2320        {
2321                if (save_last == eSCREEN_MAX)
2322                        p_screen_new->last_screen_id = p_app->screen_id;
2323                else
2324                {
2325                        p_screen_new->last_screen_id = save_last;
2326                        p_screen->button_selection = 0; /* if we do not save the last screen, clear out focus history */
2327                }
2328
2329                if (id < eSCREEN_MAX)
2330                        p_app->screen_id = id;
2331#ifdef CONFIG_EIA_708
2332                if (id > eSCREEN_NULL) {
2333                        if (p_app->cc_enabled)
2334                                bapp_enable_cc(p_app, false);
2335                }
2336#endif
2337        }
2338
2339        if (p_app->screen_id == eSCREEN_MAX)
2340        {
2341                p_app->screen_id = eSCREEN_BANNER; /* Default to channel change screen */
2342        }
2343        BDBG_WRN(("Changing screen from %d to %d\n",cur_screen, p_app->screen_id));
2344
2345}
2346
2347/*
2348Summary:
2349sets the current screen for display to be the last screen
2350Description:
2351sets the current screen for display to be the last screen
2352 */
2353void bapp_goto_last_screen(bapp_t *p_app)
2354{
2355        bscreen_t *p_screen     = &(p_app->p_screens[p_app->screen_id]);
2356        p_app->screen_id = p_screen->last_screen_id;
2357        if (p_app->screen_id == eSCREEN_MAX)
2358        {
2359                p_app->screen_id = eSCREEN_BANNER; /* Default to channel change screen */
2360        }
2361}
2362
2363#ifndef NO_VCHIP
2364/*
2365 * Summary:
2366 * Handle content advisory blocking/unblocking.
2367 * Returns 1 if blocking/unblocking results in a screen change, 0 otherwise
2368 *  */
2369int bapp_handle_blocking(bapp_t *p_app)
2370{
2371        int     screen_changed = 0;
2372
2373        if (p_app->ratings_override)
2374                return screen_changed;
2375
2376        BDBG_MSG(("last_psip_rating_block_status:%d last_rating_block_status:%d\n",
2377                                p_app->last_psip_rating_block_status ,p_app->last_rating_block_status));
2378
2379        /* check both types of ratings - if either one says "block", we block */
2380        if ((p_app->last_psip_rating_block_status == 1) || (p_app->last_rating_block_status == 1))
2381        {
2382                /* show pin verification screen if not in menus */
2383                if ((p_app->screen_id == eSCREEN_BANNER_SMALL) ||
2384                                (p_app->screen_id == eSCREEN_NULL))
2385                {
2386                        bapp_set_current_screen(p_app, eSCREEN_PIN_VERIFY_LIVE, eSCREEN_NULL);
2387                        screen_changed = 1;
2388                }
2389        } else
2390        {
2391                /* no blocking, need to re-enable decode and possibly hide pin verification screen */
2392                if ((p_app->screen_id == eSCREEN_PIN_VERIFY_LIVE) ||
2393                                (p_app->screen_id == eSCREEN_WRONG_PIN_LIVE))
2394                {
2395                        bapp_set_current_screen(p_app, eSCREEN_NULL, eSCREEN_NULL);
2396                        screen_changed = 1;
2397                }
2398        }
2399        return screen_changed;
2400}
2401#endif
2402
2403/* TODO: */
2404void bapp_power(bapp_t *p_app, bool power)
2405{
2406        bapp_standby(p_app, power);
2407}
2408/*
2409Summary:
2410Enter/exit standby
2411 */
2412static void bapp_standby(bapp_t *p_app, bool power)
2413{
2414        AC_standby();
2415       
2416        if (!power && p_app->check_poweron)
2417        {
2418                return;
2419        }
2420
2421        if (power)
2422        {
2423                /* turning power on */
2424                BDBG_ERR(("######## Turn ON ########\n"));
2425#ifdef CONFIG_STANDBY
2426                bpwr_control(p_app, false);
2427                bos_sleep(100);
2428                p_app->chm.force_tune = true;
2429                bapp_tune(p_app);
2430#endif
2431                bapp_av_mute(p_app, 0);
2432                buser_AOV_input_LED(p_app->p_rfm,eLED_Status_G);
2433        } else
2434        {
2435                BDBG_ERR(("######## Turn OFF ########\n"));
2436#ifdef CONFIG_NXP_TDA182I4
2437#ifdef MERGE_20121115
2438                NXP_TDA182I4_SetLoopThrough(true);/*janzy@20121108,add NXP_TDA182I4_SetLoopThrough*/
2439#endif
2440                NXP_TDA182I4_SetStandby();
2441#endif
2442                bapp_av_mute(p_app,1);
2443                buser_AOV_input_LED(p_app->p_rfm,eLED_Status_R);
2444                if (p_app->settings_dirty)
2445                        bapp_save_settings(p_app);
2446                /* turning power off */
2447#ifdef CONFIG_STANDBY
2448                if (p_app->active_standby) 
2449                {
2450                        bpwr_control(p_app, true);
2451                }
2452                else 
2453                {
2454                        b_s3_standby(USERIO_ID);
2455                        /* don't switch task, experimental till figure out the issue */
2456                        while (1);
2457                }
2458#endif
2459        }
2460        p_app->power = power;
2461}
2462
2463#ifdef OLD_INFO_KEY_PROCESSING
2464/*
2465 * Summary:
2466 * Handle diag events.
2467 * */
2468static bool bapp_enter_diag(bapp_t *p_app,bIR_codes_t code)
2469{
2470        bool result = false;
2471        switch (code)
2472        {
2473                case eIR_INFO:
2474                        bapp_set_current_screen(p_app, eSCREEN_DIAG_MENU, eSCREEN_MAX);
2475                        bapp_new_screen(p_app);
2476                        result = true;
2477                        break;
2478                default:
2479                        break;
2480        }
2481        return result;
2482}
2483#endif
2484/*
2485Summary:
2486key sequence add.
2487*/
2488
2489
2490#define seq_len 4
2491
2492typedef enum
2493{
2494                NONE=0,
2495                RF3,
2496                RF4,
2497}key_id;
2498
2499
2500typedef struct 
2501{
2502        key_id id;
2503        int num_key;
2504        bIR_codes_t keys[seq_len];
2505}keyseqmem;
2506
2507keyseqmem s_keyseq[] =
2508{
2509        {RF3,3,{eIR_DOT,eIR_3,eIR_MUTE}},
2510        {RF4,3,{eIR_DOT,eIR_4,eIR_MUTE}},
2511        {NONE,}
2512};
2513
2514key_id p_check_key_sequence(bapp_t *p_app,buser_input_event *p_event)
2515{
2516        int i;
2517        static bIR_codes_t keyseq[seq_len]; // 4°¡Áö Á¶ÇÕ°¡Áö »ý¼º.
2518        bool key_up = (p_event->code & 0x40000000) ? true : false;
2519
2520#ifdef OLD_INFO_KEY_PROCESSING
2521                b_timeval cur_tv;
2522#endif
2523
2524////////        key_up ¿¡¼­ ½ÇÇà
2525        if(key_up){
2526//              printf("\n----- keyseq[3]:%x [2]:%x [1]:%x [0]:%x -------\n",keyseq[3],keyseq[2],keyseq[1],keyseq[0]);
2527#ifdef OLD_INFO_KEY_PROCESSING
2528                if ((p_app->last_key_down == eIR_MUTE))
2529                {
2530                        GETTIMEOFDAY(&cur_tv);
2531                        if ((p_app->last_key_tv.tv_sec + 3) <= cur_tv.tv_sec)
2532                        {
2533                                memcpy(&keyseq[0],&keyseq[1],sizeof(keyseq)-sizeof(keyseq[0])); //shift to front
2534                                keyseq[seq_len-1] = p_app->last_key_down;
2535                        }
2536                }
2537
2538#endif
2539                if ((p_app->last_key_down != eIR_MUTE)){
2540                // add (append) key history queue
2541                memcpy(&keyseq[0],&keyseq[1],sizeof(keyseq)-sizeof(keyseq[0])); //shift to front
2542                keyseq[seq_len-1] = p_app->last_key_down;
2543                }
2544        }
2545///////////
2546        for (i=0; s_keyseq[i].id!=NONE; i++)
2547        {
2548                if (memcmp(&keyseq[seq_len-s_keyseq[i].num_key],s_keyseq[i].keys,s_keyseq[i].num_key*sizeof(bIR_codes_t))==0){
2549                        memset(keyseq,0,sizeof(keyseq));
2550                        return s_keyseq[i].id;
2551                }
2552        }
2553        return 0;
2554}
2555
2556/*
2557Summary:
2558RF3 ->0  RF4 ->1
2559*/
2560void RF_process(bapp_t *p_app,int val)
2561{
2562        p_app->audio_mute = false;
2563        bapp_audio_mute(p_app, p_app->audio_mute);
2564        p_app->settings.rfm=val;
2565        brfm_set_ch3(p_app->p_rfm, p_app->settings.rfm);
2566}
2567
2568
2569/*
2570Summary:
2571Handle user events.
2572 */
2573static void bapp_handle_user_event(bapp_t *p_app,
2574                buser_input_event *p_event
2575                )
2576{
2577        bscreen_event_t screen_event;
2578        bool key_up = (p_event->code & 0x40000000) ? true : false;
2579        bIR_codes_t code = (bIR_codes_t)(p_event->code & ~0x40000000);
2580        static int rfm;
2581        static int RF_change=0;
2582
2583#ifdef OLD_INFO_KEY_PROCESSING
2584        b_timeval cur_tv;
2585#endif
2586
2587        BDBG_WRN(("%s 0x%02x(%s)",__FUNCTION__,code,(key_up) ? "up" : "down"));
2588
2589        switch (code)
2590        {
2591#ifdef CONFIG_STANDBY
2592                case eIR_POWER:
2593                        if (key_up && !p_app->check_poweron) {
2594                                if (p_app->settings.auto_power_off) {
2595                                        p_app->chm_cmd.cmd_id = eCHM_INFO;
2596                                        chm_cmd(&p_app->chm, &p_app->chm_cmd);
2597                                }
2598                                p_app->active_standby = 0;
2599                                bapp_standby(p_app, !p_app->power);
2600                        }
2601                        break;
2602#else
2603                case eIR_POWER:
2604                        if (key_up && !p_app->check_poweron) {
2605                                if (p_app->settings.auto_power_off) {
2606                                        p_app->chm_cmd.cmd_id = eCHM_INFO;
2607                                        chm_cmd(&p_app->chm, &p_app->chm_cmd);
2608                                }
2609                                bapp_standby(p_app, !p_app->power);
2610                        }
2611                        break;
2612#endif
2613
2614                default:
2615#ifdef CONFIG_STANDBY
2616                        if (!p_app->power) 
2617                                break;
2618#endif
2619
2620                        /* Test to see if we should enter the diagnostic state */
2621#ifdef OLD_INFO_KEY_PROCESSING
2622                        if (key_up && (p_app->last_key_down == code) && !p_app->settings.av_mute)
2623                        {
2624                                GETTIMEOFDAY(&cur_tv);
2625                                if ((p_app->last_key_tv.tv_sec + BAPP_DIAG_TIMEOUT) <= cur_tv.tv_sec)
2626                                {
2627                                        if (bapp_enter_diag(p_app,code))
2628                                                break;
2629                                }
2630                        }
2631                       
2632#endif
2633                        //RF 3/4 sequence add
2634                        switch(p_check_key_sequence(p_app,p_event))
2635                        {
2636                                case RF3:
2637                                        RF_process(p_app,0);
2638                                        break;
2639                                case RF4:
2640                                        RF_process(p_app,1);
2641                                        break;
2642                                default:
2643                                        break;
2644                        }       
2645                       
2646                        if(p_app->last_key_down== eIR_RF3)                             
2647                                RF_process(p_app,0);
2648
2649                        if(p_app->last_key_down== eIR_RF4)
2650                                RF_process(p_app,1);
2651                       
2652
2653                        if ((p_app->state != eAPP_STATE_NORMAL) && (p_app->screen_id == eSCREEN_BANNER)) 
2654                                break;
2655
2656                        screen_event.type = eS_EVENT_IR;
2657                        screen_event.id = p_event->code;
2658
2659                        if (p_app->p_screens[p_app->screen_id].handle_event(p_app,
2660                                                (void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
2661                        {
2662                                BDBG_MSG(("%s screen_id=%d",__FUNCTION__,p_app->screen_id));
2663                                /* Wait for vsync then do screen drawing */
2664                                bapp_new_screen(p_app);
2665                        } else
2666                        {
2667                                bapp_handle_event(p_app,&screen_event);
2668                        }
2669                       
2670
2671               
2672                        break;
2673        }
2674
2675        if (p_app->state != eAPP_STATE_FACTORY)
2676        {
2677        }
2678
2679        if (!key_up)
2680        {
2681                //BDBG_WRN(("%s: !key_up \n",__FUNCTION__));
2682                p_app->last_key_down = code;
2683                GETTIMEOFDAY(&p_app->last_key_tv);
2684        }
2685#ifdef OLD_INFO_KEY_PROCESSING
2686        else
2687        {
2688                BDBG_WRN(("%s: key_up \n",__FUNCTION__));
2689                p_app->last_key_down = (bIR_codes_t)0xFFF; /* key up */
2690        }
2691#endif
2692}
2693/*
2694Summary:
2695Handle rrt events.Need requirements to implement correct handling.
2696 */
2697static bapp_state_t bapp_handle_set_screen_event(bapp_t *p_app, 
2698                chm_event_t *p_event)
2699
2700{
2701        bapp_set_current_screen(p_app, p_event->id, eSCREEN_MAX);
2702        bapp_new_screen(p_app);
2703        return eAPP_STATE_NORMAL;
2704}
2705
2706/*
2707Summary:
2708Handle channel manager events.
2709 */
2710static bapp_state_t bapp_handle_chm_event(bapp_t *p_app)
2711{
2712        bscreen_event_t screen_event;
2713        chm_event_t *p_event;
2714        b_timeval start_tv;
2715        static int scan_ch_cnt = 0;
2716        bapp_state_t new_state = p_app->state;
2717
2718        /* Check for notification events */
2719        if ((p_event = (chm_event_t*)bos_pend_event(p_app->msg_queue,0)) != NULL)
2720        {
2721                screen_event.type = eS_EVENT_MAX;
2722                screen_event.id = p_event->id;
2723
2724                switch (p_event->type)
2725                {
2726                        case eCHM_EVT_SET_SCREEN:               /* set current screen event */
2727                                new_state = bapp_handle_set_screen_event(p_app,p_event);
2728                                break;
2729                        case eCHM_EVT_CANCEL: screen_event.type = eS_EVENT_CANCEL; break;
2730                        case eCHM_EVT_DONE: screen_event.type = eS_EVENT_DONE; break;
2731                        case eCHM_EVT_REDRAW: screen_event.type = eS_EVENT_REDRAW; break;
2732                        case eCHM_EVT_SIGNAL:
2733                                                                  {
2734                                                                          chm_signal_event_t *p_sig = (chm_signal_event_t*)p_event;
2735                                                                          p_app->lock = (p_sig->lock) ? true : false;
2736                                                                          p_app->power_level = p_sig->power;
2737                                                                          p_app->tuned_freq = p_sig->freq_hz;
2738                                                                          p_app->snr = p_sig->SNR;
2739                                                                          p_app->signal_quality = p_sig->signal_quality;
2740                                                                          if (p_app->screen_id == eSCREEN_ANTENNA) {
2741                                                                                  screen_event.type = eS_EVENT_PROGRESS;
2742                                                                                  screen_event.id = p_app->power_level;
2743                                                                          }
2744                                                                  }
2745                                                                  break;
2746
2747#ifndef NO_VCHIP
2748                        case eCHM_EVT_CAD:
2749                                                                  {
2750                                                                          unsigned char blocked;
2751                                                                          unsigned char region,dim,val;
2752                                                                          b_timeval tv;
2753                                                                          uint32_t current_ticks = bos_getticks();
2754
2755                                                                          /* ignore rating if ratings was received while tuned to a different channel. */
2756                                                                          if (current_ticks < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
2757                                                                                  break;
2758
2759                                                                          GETTIMEOFDAY(&tv);
2760                                                                          //BDBG_WRN(("PSIP Ratings @ %d\n",tv.tv_sec));
2761                                                                          s_p_app->last_cad = tv.tv_sec;
2762                                                                          blocked = (uint8_t)(screen_event.id >> 24) & 0xFF;
2763                                                                          region  = (uint8_t)(screen_event.id >> 16) & 0xFF;
2764                                                                          dim = (uint8_t)(screen_event.id >> 8) & 0xFF;
2765                                                                          val = (uint8_t)(screen_event.id & 0xFF);
2766
2767                                                                          if ((s_p_app->ratings_region != region) || (s_p_app->ratings_dim != dim) || (s_p_app->ratings_val != val))
2768                                                                          {
2769                                                                                  s_p_app->ratings_region = region;
2770                                                                                  s_p_app->ratings_dim = dim;
2771                                                                                  s_p_app->ratings_val = val;
2772                                                                          }
2773
2774                                                                          p_app->last_psip_rating_block_status = blocked;
2775                                                                          if (bapp_handle_blocking(p_app))
2776                                                                                  screen_event.type = eS_EVENT_SETUP;
2777                                                                          else /* Update OSD */
2778                                                                                  screen_event.type = eS_EVENT_REDRAW;
2779                                                                  }
2780                                                                  break;
2781
2782                        case eCHM_EVT_BLOCK:
2783                                                                  /* ignore rating if ratings was received while tuned to a different channel. */
2784                                                                  if (bos_getticks() < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
2785                                                                          break;
2786
2787                                                                  /* p_app->last_rating_block_status = screen_event.id; - not necessary because already updated by bapp_xds_callback() */   
2788                                                                  if (bapp_handle_blocking(p_app)) {
2789                                                                          screen_event.type = eS_EVENT_SETUP;
2790                                                                  }
2791                                                                  break;
2792
2793                        case eCHM_EVT_RRT:
2794                                                                  {
2795                                                                          unsigned char rating_region;
2796                                                                          unsigned char version_number;
2797                                                                          uint32_t current_ticks = bos_getticks();
2798
2799                                                                          if (p_app->settings.ratings.ratings_lock < 2)
2800                                                                                  break;
2801
2802                                                                          /* ignore rating if ratings was received while tuned to a different channel. */
2803                                                                          if (current_ticks < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
2804                                                                                  break;
2805
2806                                                                          rating_region     = (uint8_t)(screen_event.id >> 8) & 0xFF;
2807                                                                          version_number    = (uint8_t)(screen_event.id & 0x1F);
2808                                                                          if (rating_region == 1)
2809                                                                                  break;
2810
2811                                                                          /* this will be dealt with in the default screen idle loop since we only want
2812                                                                                 to alter rrt settings when the user is not in the menu system. */
2813                                                                          if (screen_event.id != p_app->settings.rrt_settings.last_rrt_id)
2814                                                                          {
2815                                                                                  BDBG_WRN(("### NEW RRT(0x%02x,0x%02x) ###\n",rating_region,version_number));
2816                                                                                  p_app->settings.rrt_settings.last_rrt_id = screen_event.id;
2817                                                                                  p_app->settings.rrt_settings.rrt_status = eRRT_AVAILABLE;
2818                                                                                  switch (p_app->screen_id)
2819                                                                                  {
2820                                                                                          case eSCREEN_RATINGS:
2821                                                                                          case eSCREEN_RATINGS_LOCK:
2822                                                                                          case eSCREEN_RATINGS_LIMITS:
2823                                                                                          case eSCREEN_RATINGS_TV:
2824                                                                                          case eSCREEN_RATINGS_MOVIES:
2825                                                                                          case eSCREEN_RATINGS_RRT_DIM:
2826                                                                                          case eSCREEN_RATINGS_RRT_VAL:
2827                                                                                          case eSCREEN_RATINGS_RRT_UPDATE:
2828                                                                                                  bapp_set_current_screen(p_app, eSCREEN_RATINGS_RRT_UPDATE, eSCREEN_NULL);
2829                                                                                                  bapp_new_screen(p_app);
2830                                                                                                  break;
2831                                                                                          default:
2832                                                                                                  bapp_set_current_screen(p_app, eSCREEN_RATINGS_RRT_UPDATE, eSCREEN_MAX);
2833                                                                                                  bapp_new_screen(p_app);
2834                                                                                                  break;
2835                                                                                  }
2836                                                                          }
2837                                                                  }
2838
2839                                                                  break;
2840#endif
2841                        case eCHM_EVT_EAS:
2842                                                                  BDBG_MSG(("%s:%d EAS TIMER STARTED",__FUNCTION__,__LINE__)); 
2843                                                                  if ((p_app->state == eAPP_STATE_NORMAL) && 
2844                                                                                  (p_app->screen_id == eSCREEN_BANNER ||
2845                                                                                   p_app->screen_id == eSCREEN_WIZ_CH_SCAN || 
2846                                                                                   p_app->screen_id == eSCREEN_BANNER_SMALL || 
2847                                                                                   p_app->screen_id == eSCREEN_GUIDE))
2848                                                                  {
2849                                                                          GETTIMEOFDAY(&start_tv);
2850
2851                                                                          p_app->eas_timeout = start_tv.tv_sec + p_event->ticks;
2852                                                                          /* for default: eas_one_iterlation completed as soon as eas display starts */
2853                                                                          //p_app->eas_one_iteration = true;
2854#ifdef CONFIG_EIA_708
2855                                                                          bapp_enable_cc(p_app, false);
2856#endif
2857                                                                          /* with this flag, we don't null eas sequence number */
2858                                                                          if ((bscreen_eas_text_scrolling_info(p_app, p_app->eas_buf, p_app->eas_buf_size)==BERR_SUCCESS) &&
2859                                                                                          p_app->eas_text) {
2860                                                                                  p_app->eas_started = true;
2861                                                                                  if (p_event->data[0]) { /* channel found */
2862                                                                                          p_app->cur_ch_num = p_event->id && 0xFFFF;
2863                                                                                          bapp_tune(p_app);
2864                                                                                  }
2865                                                                                  p_app->eas_ch_found = p_event->data[0];
2866                                                                          }
2867                                                                  }
2868                                                                  break;
2869
2870                        case eCHM_EVT_STATUS:
2871                                                                  switch (p_event->id)
2872                                                                  {
2873#if 0
2874                                                                          case eCHM_STATUS_HUNT: /* HUNT MODE */
2875                                                                                  BDBG_WRN(("eCHM_STATUS_HUNT %d", p_app->scan_in_progress));
2876                                                                                  if (!p_app->scan_in_progress) {
2877                                                                                          bapp_eval_state(p_app,eAPP_STATE_HUNT);
2878                                                                                          scan_ch_cnt = 0;
2879                                                                                          BDBG_WRN(("eCHM_STATUS_HUNT\n"));
2880                                                                                  }
2881                                                                                  break;
2882#endif
2883                                                                          case eCHM_STATUS_CHMAP:
2884                                                                                  BDBG_WRN(("eCHM_STATUS_CHMAP flags = 0x%08x\n",p_event->ticks));
2885                                                                                  if (p_app->settings.num_channels > 0 && (2 == p_event->ticks)) {
2886                                                                                          /* channels have been added during channel scan, so no need to copy */
2887                                                                                          if (p_app->cur_ch_num > 0) { 
2888                                                                                                  if (p_app->cur_ch_num >= p_app->settings.num_channels) {
2889                                                                                                          p_app->cur_ch_num = 0;
2890                                                                                                          p_app->prev_ch = p_app->cur_ch = p_app->settings.ch[p_app->cur_ch_num];
2891                                                                                                  }
2892                                                                                          }
2893                                                                                          else {
2894                                                                                                  /* new channel scan, set to 0 first */       
2895                                                                                                  p_app->cur_ch_num = 0;
2896                                                                                                  p_app->prev_ch = p_app->cur_ch = p_app->settings.ch[p_app->cur_ch_num];
2897                                                                                          }
2898                                                                                          p_app->settings_dirty |= DIRTY_CHANNEL_MAP;
2899                                                                                  } else
2900                                                                                  {
2901                                                                                          BDBG_WRN(("Channel map NOT changed\n"));
2902                                                                                  }
2903
2904                                                                                  if (p_app->settings.psi_scan && (2 == p_event->ticks))
2905                                                                                  {
2906                                                                                          p_app->settings_dirty |= DIRTY_CHANNEL;
2907                                                                                          bapp_save_settings(p_app);
2908                                                                                          bapp_load_settings(p_app);
2909                                                                                  }
2910
2911                                                                                  if ((p_app->state == eAPP_STATE_NORMAL) && p_event->ticks)
2912                                                                                  {
2913                                                                                          /* if just scanned and have channnels, force to tune first channel  */
2914                                                                                          if (p_app->settings.num_channels && (eSCREEN_GUIDE != p_app->screen_id && (eSCREEN_CH_SCAN != p_app->screen_id) && (eSCREEN_DIAG_MENU != p_app->screen_id)))
2915                                                                                          {
2916                                                                                                  p_app->chm.last_freq_hz = true;
2917                                                                                                  p_app->chm.force_tune = true;
2918                                                                                                  bapp_audio_do_mute(p_app, false);
2919                                                                                                  bapp_audio_mute(p_app, false);
2920                                                                                                  bapp_tune(p_app);
2921                                                                                                  new_state = eAPP_STATE_NORMAL;
2922                                                                                          }
2923                                                                                  } 
2924                                                                                  else
2925                                                                                  {
2926#ifdef ACB612
2927                                                                                          if(!p_app->factory_test)
2928                                                                                                  new_state = eAPP_STATE_NORMAL;
2929#else
2930                                                                                          new_state = eAPP_STATE_NORMAL;
2931#endif
2932                                                                                  }
2933                                                                                  break;
2934
2935                                                                          case eCHM_STATUS_PAT:
2936                                                                                  p_app->has_PAT = true; 
2937                                                                                  if (p_app->screen_id == eSCREEN_CH_SCAN_PROGRESS) {
2938                                                                                          if (p_event->ticks != 0) {
2939                                                                                                  screen_event.type = eS_EVENT_PROGRESS;
2940                                                                                                  screen_event.id = p_event->ticks;
2941                                                                                                  scan_ch_cnt = p_app->settings.num_channels;
2942                                                                                                  screen_event.data = &scan_ch_cnt;
2943                                                                                          }
2944                                                                                  }
2945                                                                                  break;
2946                                                                          case eCHM_STATUS_NOPAT:
2947                                                                                  p_app->has_PAT = false; 
2948                                                                                  if (p_app->screen_id == eSCREEN_CH_SCAN_PROGRESS) {
2949                                                                                          if (p_event->ticks != 0) {
2950                                                                                                  screen_event.type = eS_EVENT_PROGRESS;
2951                                                                                                  screen_event.id = p_event->ticks;
2952                                                                                                  scan_ch_cnt = p_app->settings.num_channels;
2953                                                                                                  screen_event.data = &scan_ch_cnt;
2954                                                                                          }     
2955                                                                                  }
2956                                                                                  break;
2957                                                                          case eCHM_STATUS_TUNE_MS: p_app->tune_ms = p_event->ticks; break;
2958                                                                          case eCHM_STATUS_SI_MS: p_app->si_ms = p_event->ticks; break;
2959                                                                  }
2960                                                                  break;
2961
2962                        case eCHM_EVT_AV_MUTE:
2963                                                                  bapp_standby(p_app,!p_event->id);
2964                                                                  break;
2965
2966                        case eCHM_EVT_TIME:
2967                                                                  {
2968                                                                          chm_time_event_t *p_time_evt = (chm_time_event_t*)p_event;
2969                                                                          p_app->system_time = p_time_evt->system_time;
2970                                                                          p_app->system_offset = p_time_evt->system_offset;
2971                                                                          //p_app->settings.utc_offset = (int)p_time_evt->utc_offset;
2972                                                                          p_app->have_time = true;
2973                                                                  }
2974                                                                  break;
2975
2976                        case eCHM_EVT_RESET:
2977                                                                  switch (p_event->id)
2978                                                                  {
2979                                                                          default:
2980                                                                          case 0:       /* nop */
2981                                                                                  break;
2982                                                                          case 1:       /* reset */
2983                                                                                  bapp_do_poweroff(p_app);
2984                                                                                  break;
2985                                                                          case 2:       /* reset some */
2986                                                                                  bapp_reset_settings(p_app);
2987                                                                                  /* save everything */
2988                                                                                  p_app->settings_dirty = DIRTY_ALL;
2989                                                                                  bapp_save_settings(p_app);
2990                                                                                  bapp_do_poweroff(p_app);
2991                                                                                  break;
2992                                                                          case 3:       /* reset full */
2993                                                                                  bapp_reset_settings(p_app);
2994                                                                                  /* save everything */
2995                                                                                  p_app->settings_dirty = DIRTY_ALL;
2996                                                                                  bapp_save_settings(p_app);
2997                                                                                  /* Erase downloaded firmware here */
2998                                                                                  bapp_do_poweroff(p_app);
2999
3000                                                                                  break;
3001                                                                  }
3002                                                                  break;
3003                        case eCHM_EVT_SAVE:
3004                                                                  /* Must be careful of when this is done if running from flash */
3005                                                                  if ((p_app->settings.audio_vol != p_app->audio_vol) || p_app->settings_dirty)
3006                                                                  {
3007                                                                          p_app->settings.audio_vol = p_app->audio_vol;
3008                                                                          bapp_save_settings(p_app);
3009                                                                  }
3010                                                                  break;
3011
3012                        case eCHM_EVT_PROGRESS:
3013                                                                  if (p_app->screen_id == eSCREEN_CH_SCAN_PROGRESS) {
3014                                                                          scan_ch_cnt = p_app->settings.num_channels;
3015                                                                          screen_event.type = eS_EVENT_PROGRESS;
3016                                                                          screen_event.id = p_event->ticks;
3017                                                                          screen_event.data = &scan_ch_cnt;
3018                                                                  }
3019                                                                  else {
3020                                                                          screen_event.id = p_event->id;
3021                                                                          screen_event.type = eS_EVENT_PROGRESS;
3022                                                                  }
3023                                                                  break;
3024
3025                        default:
3026                                                                  BDBG_WRN(("%s:%d CHM EVENT = %d NOT HANDLED\n",__FUNCTION__,__LINE__,p_event->type));
3027                                                                  break;
3028                }
3029                //BDBG_MSG(("%s %s, id=0x%04x\n",__FUNCTION__,s_chm_evt_str[p_event->type], p_event->id));
3030
3031                if (p_app->p_screens[p_app->screen_id].handle_event(p_app,
3032                                        (void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
3033                {
3034                        //BDBG_MSG(("%s:%d screen_id %d\n",__FUNCTION__,__LINE__,p_app->screen_id));
3035                        /* Wait for vsync then do screen drawing */
3036                        bapp_new_screen(p_app);
3037                } else
3038                {
3039                        /* EIT update for Banner (SMALL or BIG) and GUIDE screen */
3040                        if  ((eS_EVENT_REDRAW == screen_event.type) && (1 == p_event->ticks)) {
3041                                bool redraw = false;
3042
3043                                if (eSCREEN_GUIDE == p_app->screen_id)
3044                                        redraw = true;
3045                                else if (eSCREEN_BANNER == p_app->screen_id || eSCREEN_BANNER_SMALL == p_app->screen_id) {
3046                                        banner_state_t *p_bs = (banner_state_t*)p_app->p_screens[p_app->screen_id].local_state;
3047
3048                                        redraw = (eLS_BANNER_SMALL == p_bs->mode || eLS_BANNER_BIG == p_bs->mode);
3049                                }
3050                                if (redraw) {   
3051                                        p_app->p_screens[p_app->screen_id].draw(p_app,(void*)&(p_app->p_screens[p_app->screen_id]));
3052                                        bapp_flush_screen(p_app);
3053                                }
3054                        }
3055                        bapp_handle_event(p_app,&screen_event);
3056                }
3057        }
3058        return new_state;
3059}
3060
3061/*
3062Summary:
3063Main event loop when in normal operation mode.
3064 */
3065static bapp_state_t bapp_run_main(bapp_t *p_app)
3066{
3067        buser_input_event event;
3068        unsigned event_cnt;
3069        static bscreen_event_t screen_event;
3070
3071        /* Check for UI event */
3072        if (buser_input_get_event(p_app->user_io,&event,1,&event_cnt) == b_ok)
3073        {
3074                if (event_cnt > 0)
3075                {
3076                        p_app->last_keypress_tick = bos_getticks();
3077                        /* now use power_saver_tick for tracking power saver timer so that it wouldn't be reset if signal contion changes */
3078                        p_app->power_saver_tick = bos_getticks();
3079                        bapp_handle_user_event(p_app,&event);
3080                }
3081        }
3082
3083        /* Yield control */
3084        bos_sleep(p_app->yield_ms);
3085
3086        if (!p_app->power) return p_app->state;
3087
3088        screen_event.type = eS_EVENT_IDLE;
3089        screen_event.id = 0;
3090        /* Give screen idle time to handle menu timeouts, etc */
3091        if (p_app->p_screens[p_app->screen_id].handle_event(p_app,
3092                                (void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
3093        {
3094                /* Wait for vsync then do screen drawing */
3095                bapp_new_screen(p_app);
3096        }
3097
3098        /* Do application idle time processing */
3099        bapp_idle(p_app);
3100
3101        return p_app->state;
3102}
3103
3104void bapp_channel_scan(bapp_t *p_app)
3105{
3106        p_app->chm.cmd = eCHM_CANCEL;
3107        p_app->chm_cmd.cmd_id = eCHM_CANCEL;
3108        chm_cmd(&p_app->chm,&p_app->chm_cmd);
3109
3110        p_app->settings.num_channels = 0;
3111        p_app->cur_ch_num = 0;
3112        p_app->scan_in_progress = false;
3113
3114        bapp_channel_hunt(p_app);
3115        //bos_sleep(50);
3116        bapp_eval_state(p_app,eAPP_STATE_HUNT);
3117}
3118
3119/*
3120Summary:
3121Perform a channel hunt (for cable), channel scan for NTIA box
3122 */
3123static int bapp_channel_hunt(bapp_t *p_app)
3124{
3125        p_app->hunt_cmd.cmd_id = eCHM_HUNT;
3126        chm_cmd(&p_app->chm,&p_app->hunt_cmd);
3127        return 0;
3128}
3129
3130/*
3131Summary:
3132Main app loop.
3133Description:
3134Main application event loop.
3135 */
3136#ifdef BCM_DEBUG
3137static const char *s_app_state_name[] = { "DEFAULT","HUNT","NORMAL","FACTORY","DONE"};
3138#endif
3139
3140static void bapp_eval_state(bapp_t *p_app,bapp_state_t new_state)
3141{
3142        bapp_led_set_mode(p_app);
3143        led_update(APP_DEFAULT_YIELD); 
3144        if (p_app->state == new_state)
3145                return;
3146
3147        BDBG_WRN(("from %s to %s\n",s_app_state_name[p_app->state], s_app_state_name[new_state] ));
3148
3149        /* Handle exiting current state */
3150        switch (p_app->state)
3151        {
3152                case eAPP_STATE_NORMAL:
3153                        p_app->last_screen_id = eSCREEN_MAX;
3154                        break;
3155                case eAPP_STATE_HUNT:
3156                        bapp_screen_redraw(p_app);
3157                        bos_sleep(250); /* must display full progress bar for at least 250ms before proceding */
3158                case eAPP_STATE_FACTORY:
3159                case eAPP_STATE_DEFAULT:
3160                case eAPP_STATE_DONE:
3161                        break;
3162        }
3163
3164        /* Handle entering new state */
3165        switch (new_state)
3166        {
3167                case eAPP_STATE_HUNT:
3168                        if ((p_app->screen_id != eSCREEN_CH_SCAN_PROGRESS) && (eSCREEN_FREQUENCY_CONFIGURE != p_app->screen_id)) 
3169                        {
3170                                if (p_app->power)
3171                                        bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX);
3172                                else
3173                                        bapp_set_current_screen(p_app, eSCREEN_POWER_OFF, eSCREEN_MAX);
3174                                bapp_new_screen(p_app);
3175                        }
3176#if 0
3177                        if (!p_app->scan_in_progress) {
3178                                bapp_channel_hunt(p_app);
3179                                bos_sleep(250); /* must display full progress bar for at least 250ms before proceding */
3180                        }
3181#endif
3182                        break;
3183
3184                case eAPP_STATE_NORMAL:
3185                        if ((p_app->screen_id != eSCREEN_CH_SCAN_PROGRESS) && (p_app->screen_id != eSCREEN_GUIDE) && 
3186                                        (p_app->settings.num_channels > 0)) 
3187                        {
3188                                if (p_app->power) {
3189                                        /* in wizard mode, don't change the screen through eval_state*/
3190                                        if (p_app->settings.wiz_completed)
3191                                                bapp_set_current_screen(p_app, eSCREEN_BANNER, eSCREEN_MAX);
3192                                }
3193                                else
3194                                        bapp_set_current_screen(p_app, eSCREEN_POWER_OFF, eSCREEN_MAX);
3195                        }
3196                        bapp_new_screen(p_app);
3197                        if (p_app->settings.num_channels && 
3198                                        ((eSCREEN_GUIDE != p_app->screen_id) && (eSCREEN_DIAG_MENU != p_app->screen_id))) {
3199                                p_app->chm.last_freq_hz = true;
3200                                p_app->chm.force_tune = true;
3201                                bapp_audio_do_mute(p_app, false);
3202                                bapp_audio_mute(p_app, false);
3203                                bapp_tune(p_app);
3204                        }
3205                        break;
3206                case eAPP_STATE_FACTORY:
3207                        bapp_set_current_screen(p_app, eSCREEN_STATUS, eSCREEN_MAX);
3208                        bapp_new_screen(p_app);
3209                        break;
3210                case eAPP_STATE_DEFAULT:
3211                case eAPP_STATE_DONE:
3212                        break;
3213        }
3214
3215        /* Make new state the current state */
3216        p_app->state = new_state;
3217}
3218
3219/*
3220Summary:
3221Main app loop.
3222Description:
3223Main application event loop.
3224 */
3225void bapp_run(bapp_t *p_app)
3226{
3227        bapp_state_t new_state;
3228        BDBG_WRN(("%s:%d - Start running.\n",__FUNCTION__,__LINE__));
3229
3230        while (p_app->state != eAPP_STATE_DONE)
3231        {
3232                new_state = p_app->state;
3233                switch (p_app->state)
3234                {
3235                        case eAPP_STATE_HUNT:
3236                        case eAPP_STATE_NORMAL:
3237                        case eAPP_STATE_FACTORY:
3238                                new_state = bapp_run_main(p_app);
3239                                break;
3240                        case eAPP_STATE_DEFAULT:
3241                        case eAPP_STATE_DONE:
3242
3243                                /* Yield control */
3244                                bos_sleep(p_app->yield_ms);
3245                                break;
3246                        default:
3247                                break;
3248                }
3249
3250                /* Check for chm event */
3251                if (new_state == p_app->state)
3252                        new_state = bapp_handle_chm_event(p_app);
3253
3254                bapp_eval_state(p_app,new_state);
3255        }
3256
3257        /* finish */
3258        bsettop_uninit();
3259}
3260
3261#if 0
3262/*
3263Summary:
3264Return current application channel map.
3265 */
3266ch_map_t *bapp_cur_ch_map(bapp_t *p_app)
3267{
3268        return &(p_app->settings.ch_map);
3269}
3270#endif
3271
3272/*
3273Summary:
3274        Channel Up or Down for previous or next favorite channel if any
3275Description:
3276        To go to previous/next faviorite channel if any. If no favorite channel set, then stay current channel
3277 */
3278int bapp_change_channel_fav(bapp_t *p_app, int ch_up, int tune)
3279{
3280        int retval = -1, i, j, cur;
3281
3282        BDBG_WRN(("%s (up=%d,tune=%d)\n",__func__,ch_up,tune));
3283
3284        if (p_app->settings.num_channels < 2)
3285                return retval;
3286
3287        j = cur = p_app->cur_ch_num;
3288NEXT_FAV_CHANNEL:
3289        if (ch_up)
3290        {
3291                i = (j + 1) % p_app->settings.num_channels;     
3292        }
3293        else
3294        {
3295                i = (j - 1);
3296                if (i < 0)
3297                        i = (p_app->settings.num_channels - 1);
3298        }
3299        if (p_app->settings.ch[i].skip) {
3300                if (i != cur) {
3301                        if (ch_up)
3302                                j = (j + 1) % p_app->settings.num_channels; 
3303                        else
3304                        {
3305                                j--;
3306                                if (j < 0)
3307                                        j = (p_app->settings.num_channels - 1);
3308                        }
3309                        goto NEXT_FAV_CHANNEL;
3310                }
3311                else {
3312                        /* what do we need to do */
3313                }
3314        }
3315        if (!p_app->settings.ch[i].favorite) {
3316                if (i != cur) {
3317            if (ch_up)
3318                j = (j + 1) % p_app->settings.num_channels;
3319            else
3320            {
3321                j--;
3322                if (j < 0)
3323                    j = (p_app->settings.num_channels - 1);
3324            }
3325            goto NEXT_FAV_CHANNEL;
3326                }
3327        }
3328        p_app->cur_ch_num = i;
3329
3330        if (tune)
3331        {
3332                /* make sure current one is not skip */
3333                if (!p_app->settings.ch[i].skip) {
3334                        retval = bapp_tune(p_app);
3335                        if (i != cur) {
3336                                p_app->settings_dirty |= DIRTY_CHANNEL;
3337                        }
3338                }
3339        }
3340        else
3341        {
3342                if (p_app->settings.ch[i].skip)
3343                        BDBG_WRN(("Not tune: chm->state=%d, mgt_state=%d, SKIP", p_app->chm.state, p_app->chm.mgt_state));
3344                else
3345                        BDBG_WRN(("Not tune: chm->state=%d, mgt_state=%d", p_app->chm.state, p_app->chm.mgt_state));
3346                retval = 0;
3347        }
3348        return retval;
3349}
3350
3351/*
3352Summary:
3353Channel Up or Down
3354Description:
3355To go to next channel if any
3356 */
3357int bapp_change_channel(bapp_t *p_app, int ch_up, int tune)
3358{
3359        int retval = -1, i, j, cur;
3360
3361        BDBG_WRN(("%s (up=%d,tune=%d)\n",__func__,ch_up,tune));
3362
3363        if (p_app->settings.num_channels < 2)
3364                return retval;
3365
3366        j = cur = p_app->cur_ch_num;
3367NEXT_VALID_CHANNEL:
3368        if (ch_up)
3369        {
3370                i = (j + 1) % p_app->settings.num_channels;     
3371        }
3372        else
3373        {
3374                i = (j - 1);
3375                if (i < 0)
3376                        i = (p_app->settings.num_channels - 1);
3377        }
3378        if (p_app->settings.ch[i].skip) {
3379                if (i != cur) {
3380                        if (ch_up)
3381                                j = (j + 1) % p_app->settings.num_channels; 
3382                        else
3383                        {
3384                                j--;
3385                                if (j < 0)
3386                                        j = (p_app->settings.num_channels - 1);
3387                        }
3388                        goto NEXT_VALID_CHANNEL;
3389                }
3390                else {
3391                        /* what do we need to do */
3392                }
3393        }
3394        p_app->cur_ch_num = i;
3395
3396        if (tune)
3397        {
3398                /* make sure current one is not skip */
3399                if (!p_app->settings.ch[i].skip) {
3400                        retval = bapp_tune(p_app);
3401                        if (i != cur) {
3402                                p_app->settings_dirty |= DIRTY_CHANNEL;
3403                        }
3404                }
3405        }
3406        else
3407        {
3408                if (p_app->settings.ch[i].skip)
3409                        BDBG_WRN(("Not tune: chm->state=%d, mgt_state=%d, SKIP", p_app->chm.state, p_app->chm.mgt_state));
3410                else
3411                        BDBG_WRN(("Not tune: chm->state=%d, mgt_state=%d", p_app->chm.state, p_app->chm.mgt_state));
3412                retval = 0;
3413        }
3414        return retval;
3415}
3416
3417/*
3418Summary:
3419Tune to the specified channel given by major and minor
3420Description:
3421Tune to the specified channel or nearest to the channel. Returns non-zero on failure.
3422 */
3423int bapp_set_channel_by_major(bapp_t *p_app, int major, int minor)
3424{
3425        int retval = -1; 
3426        int i, first_minor = -1;
3427        bapp_ch_t *pch = NULL;
3428
3429        BDBG_WRN(("%s %d%.%d\n",__func__, major, minor));
3430
3431        if (p_app->settings.num_channels < 1)
3432                return 0;
3433
3434        for (i = 0; i < p_app->settings.num_channels; i++) {
3435                pch = &p_app->settings.ch[i];
3436                if (pch->major == major) {
3437                        /* find major, and now look for minor match, if not, take first one */
3438                        if (pch->minor == minor) {
3439                                break;
3440                        }
3441                        if (-1 == first_minor)
3442                                first_minor = i;
3443                }
3444        }
3445        if (i >= p_app->settings.num_channels) {
3446                /* no match found */
3447                if (-1 == first_minor)
3448                        return retval;
3449                i = first_minor;
3450        }
3451        if (pch->hidden) 
3452        {
3453                BDBG_WRN(("%s Hidden channel %d.%d\n",__FUNCTION__,major, minor));
3454                return 0;
3455        }
3456        p_app->cur_ch_num = i;
3457
3458        p_app->settings_dirty |= DIRTY_CHANNEL;
3459        retval = bapp_tune(p_app);
3460
3461        return retval;
3462}
3463
3464/*
3465Summary:
3466Tune to the specified channel.
3467Description:
3468Tune to the specified channel or nearest to the channel. Returns non-zero on failure.
3469 */
3470int bapp_set_channel(bapp_t *p_app, bapp_ch_t *pch)
3471{
3472        int retval = -1; 
3473        int i;
3474
3475        BDBG_MSG(("%s %d.%d\n",__func__, pch->major, pch->minor));
3476
3477        if (pch->hidden) 
3478        {
3479                BDBG_WRN(("%s Hidden channel %d.%d\n",__FUNCTION__,pch->major, pch->minor));
3480                return 0;
3481        }
3482        /* currently do nothing, will let user to define the behaviour, later */
3483        if (pch->skip) {
3484                BDBG_WRN(("%s Skip channel %d.%d\n",__FUNCTION__,pch->major, pch->minor));
3485                return 0;
3486        }
3487        /* don't check major/minor but just set whatever channel user selection, in case there are duplicate major/minor and the user select it from with EPG screen */
3488        p_app->settings_dirty |= DIRTY_CHANNEL;
3489        retval = bapp_tune(p_app);
3490        return retval;
3491}
3492
3493/*
3494Summary:
3495Tune to the current channel.
3496 */
3497int bapp_tune(bapp_t *p_app)
3498{   
3499        bapp_ch_t tmp_prev_ch;
3500        BDBG_MSG(("%s",__func__));
3501
3502        if (p_app->settings.av_mute)
3503                return 0;
3504
3505#ifndef NO_VCHIP
3506        if (p_app->ratings_override_set)
3507        {
3508                p_app->ratings_override_set = false;
3509        }
3510        p_app->ratings_override     = false;
3511
3512        /* reset so ratings will be re-evaluated when returned to full tv */
3513        p_app->last_rating_block_status = -1;
3514        /* assume psip unblock */
3515        p_app->last_psip_rating_block_status = 0;
3516        /* clear ratings string */
3517        p_app->prog_rating_str[0] = 0;
3518        p_app->psip_rating_str[0] = 0;
3519#endif
3520
3521        /* remember previous channel so that we can go back, e.g. EAS turned */
3522        tmp_prev_ch = p_app->prev_ch;
3523        p_app->prev_ch = p_app->cur_ch;
3524
3525        /* set current channel */
3526        p_app->cur_ch = p_app->settings.ch[p_app->cur_ch_num];
3527        if (p_app->decoding)
3528        {
3529                /* TODO */
3530        }
3531        /* if they are same, use previous saved one */
3532        if ((p_app->prev_ch.major == p_app->cur_ch.major) && (p_app->prev_ch.minor == p_app->cur_ch.minor))
3533                p_app->prev_ch = tmp_prev_ch;
3534
3535        p_app->lock = false;
3536        /* need to update as it will be late in updating in the chm_tune time in Banner UI */
3537        p_app->num_sap = p_app->cur_ch.num_audio;
3538        p_app->current_sap = p_app->cur_ch.cur_audio;
3539        /* don't reset power level as in general, there should be some power, so it is better than show 0 */
3540        //p_app->power_level = 0;
3541        p_app->signal_quality = 0;
3542
3543        p_app->tune_cmd.cmd_id = eCHM_TUNE;
3544        p_app->tune_cmd.type = eCHM_CURRENT;
3545        chm_cmd(&p_app->chm,(chm_cmd_event_t*)&p_app->tune_cmd);
3546        p_app->decoding         = true;
3547        p_app->last_tune_tick   = bos_getticks();
3548
3549        /* reset audio channel timeout in case it is audio only channel */
3550        GETTIMEOFDAY(&p_app->audio_channel_tm);
3551
3552        return 0;
3553}
3554/*
3555Summary:
3556Tune to the current channel.
3557 */
3558int bapp_tune_prev(bapp_t *p_app)
3559{
3560        return bapp_set_channel(p_app, &p_app->prev_ch);
3561}
3562
3563/*
3564Summary:
3565Restart audio decode (after SAP swap audio PID)
3566 */
3567int bapp_rotate_audio_sap(bapp_t *p_app)
3568{
3569        bapp_ch_t *pch;
3570        int i;
3571
3572        pch = &p_app->settings.ch[p_app->cur_ch_num];
3573        for (i = 0; (i < MAX_AUDIO_PIDS - 1); i++) {
3574                pch->cur_audio++;
3575                pch->cur_audio %= MAX_AUDIO_PIDS;
3576                if (pch->audio_pid[pch->cur_audio])
3577                        break;
3578        }
3579        p_app->current_sap = pch->cur_audio;
3580
3581        /* the SAP audio rotate function is moved to chan_mgr.c */
3582        p_app->chm_cmd.cmd_id = eCHM_SAP;
3583        chm_cmd(&p_app->chm,&p_app->chm_cmd);
3584        return 0;
3585}
3586
3587/*
3588Summary:
3589set CLUT
3590 */
3591void bapp_set_palette(bapp_t *p_app, bapp_palette_t palette)
3592{
3593#ifndef CONFIG_GFX_ARGB32
3594        unsigned int *clut;      /* [out] address of palette */
3595        int width;                              /* [out] width of the OSD surface  */
3596        int height;                             /* [out] height of the OSD surface  */
3597        int pitch;                              /* [out] pitch of the OSD surface  */
3598        unsigned int *p_palette;
3599        unsigned int size;
3600        bgraphics_get_framebuffer(p_app->graphics,(void**)&p_app->osd_mem,(unsigned int **)&clut,&width,&height,&pitch);
3601
3602        switch (palette) 
3603        {
3604                case ePALETTE_SCREENSAVER:
3605                        if (p_app->logo)
3606                        {
3607                                bcm_raw_8_t *p_header = (bcm_raw_8_t *)p_app->logo;
3608                                uint8_t *p_clut = (uint8_t *)p_header;
3609                                p_clut += sizeof(bcm_raw_8_t);
3610                                memcpy(clut, p_clut, p_header->clut_size*sizeof(unsigned int));
3611                        }
3612                        else if (bapp_palette_get(ePALETTE_LOGO, &p_palette, &size) == b_ok)
3613                        {
3614                                BKNI_Memcpy(clut, p_palette, size*sizeof(p_palette[0]));
3615                        }
3616                        bgraphics_load_palette(p_app->graphics);
3617                        break;
3618                case ePALETTE_DEFAULT:
3619                default:
3620                        if (bapp_palette_get(palette,&p_palette,&size) == b_ok) {
3621                                BKNI_Memcpy(clut,p_palette,size*sizeof(p_palette[0]));
3622                                bgraphics_load_palette(p_app->graphics);
3623                        }
3624                        break;
3625        }
3626#endif
3627}
3628
3629/*
3630Summary:
3631returns true is sufficient signal strength, false otherwise
3632always returns true for TUNE_DURATION msecs after tuning begins.
3633 */
3634bool bapp_get_signal_status(bapp_t *p_app)
3635{
3636        static bool     first_call           = true;
3637        static bool     good_signal          = true;
3638        static uint32_t last_video_pts       = 0;
3639        static uint32_t last_video_pts_ticks = 0;
3640        static uint32_t last_audio_pts       = 0;
3641        bdecode_config cfg;
3642        static bdecode_status    status;
3643        static baudio_decode_status     audio_status;
3644
3645        uint32_t          current_ticks = bos_getticks();
3646
3647        /* If the decode is stopped dont report bad signal */
3648        if (p_app->decoding == false)
3649                return true;
3650
3651        /* check for tune duration timeout - this is used to restrict display of the 'no signal'
3652           popup for a period of time (TUNE_DURATION) after tuning */
3653        if (current_ticks < (p_app->last_tune_tick + MS_TO_TICKS(TUNE_DURATION)))
3654                return true;
3655
3656        if (p_app->settings.num_channels < 1)
3657                return false;
3658
3659        /* if first time calling function get baseline video pts
3660         * then wait 500msecs and continue.  since we require 2 samples
3661         * of decoder status at least 500msecs apart to determine signal
3662         * status, we need to "prime the pump" on the very first call only
3663         */
3664        if (first_call)
3665        {
3666                first_call = false;
3667                bdecode_get_status(p_app->decode,&status);
3668                baudio_decode_get_status(p_app->audio, &audio_status);
3669                last_video_pts       = status.video_pts;
3670                last_video_pts_ticks = current_ticks;
3671                bos_sleep(500);
3672                current_ticks = bos_getticks();
3673
3674                last_audio_pts      = audio_status.pts;
3675        }
3676
3677        /* make sure video pts is changing - indicates successful decoding.
3678         * only check every 500msecs or so
3679         */
3680        if ((current_ticks - last_video_pts_ticks) > MS_TO_TICKS(500))
3681        {
3682                bdecode_get_status(p_app->decode,&status);
3683                baudio_decode_get_status(p_app->audio, &audio_status);
3684
3685                /* if pts is changing, we are decoding properly */
3686                good_signal = (last_video_pts != status.video_pts);
3687
3688                if (good_signal == false)
3689                {
3690                        good_signal = (last_audio_pts != audio_status.pts);
3691                }
3692                last_audio_pts = audio_status.pts;
3693                //BDBG_MSG(("good_signal:%d vpts:0x%08x last_vpts:0x%08x ticks:%d", good_signal, status.video_pts, last_video_pts, current_ticks));
3694
3695                last_video_pts = status.video_pts;
3696                last_video_pts_ticks = current_ticks;
3697        }
3698
3699        bdecode_get_config(p_app->decode,&cfg);
3700        if (!good_signal)
3701        {
3702                //if (cfg.channel_change != 0 || !cfg.mute)
3703                if (!cfg.mute)
3704                {
3705                        bapp_audio_mute(p_app, 1);
3706                        cfg.mute = 1;
3707                        cfg.channel_change = 0;
3708                        bdecode_set_config(p_app->decode,&cfg);
3709                }
3710        } else
3711        {
3712                //if (cfg.channel_change != 2)
3713                if (cfg.mute)
3714                {
3715                        bapp_audio_mute(p_app, 0);
3716                        cfg.mute = 0;
3717                        cfg.channel_change = 0;         /* black instead of last video */
3718                        bdecode_set_config(p_app->decode,&cfg);
3719                }
3720        }
3721
3722        return good_signal;
3723}
3724
3725/*
3726Summary:
3727Return the current screen.
3728 */
3729
3730bscreen_t * bapp_get_current_screen(bapp_t *p_app)
3731{
3732        return &p_app->p_screens[p_app->screen_id];
3733}
3734
3735void ram_start()
3736{
3737        static bapp_t app;
3738
3739        AC_check();
3740        bapp_init(&app);
3741        bapp_run(&app);
3742}
3743
3744
3745/*
3746Summary:
3747Mute audio
3748Description:
3749Mute audio when enable is non-zero.
3750 */
3751void bapp_audio_do_mute(bapp_t *p_app, int mute)
3752{
3753        baudio_decode_config config;
3754
3755        if(p_app->factory_test)
3756                return;
3757
3758        BDBG_WRN(("%s mute = %d, audo_vol = %d, is_muted = %d...\n",__FUNCTION__,mute,p_app->audio_vol,p_app->is_muted));
3759        if (p_app->is_muted && !mute)
3760        {
3761                p_app->system_mute = (mute == 0)?false:true;
3762                return;
3763        }
3764
3765        baudio_decode_get_config(p_app->audio, &config);
3766
3767        if (mute != config.mute)
3768        {
3769                config.mute = mute;
3770                baudio_decode_set_config(p_app->audio, &config);
3771        }
3772        p_app->system_mute = (mute== 0) ? false : true;
3773}
3774
3775/*
3776 * Callback to process first pts timing profiling
3777 */
3778static void bapp_first_pts_callback(void)
3779{
3780        BDBG_WRN(("##### timing profile ####"));
3781        timing_profile_stop(s_p_app->ptp_first_pts);           
3782}
3783
3784/*
3785 * Callback to process first pts timing profiling
3786 */
3787static void bapp_seq_hdr_callback(void)
3788{
3789        BDBG_WRN(("##### timing profile ####"));
3790        timing_profile_stop(s_p_app->ptp_decode);               
3791}
3792
3793bool bapp_get_block_status(bapp_t *p_app)
3794{
3795        return false;
3796}
3797/* select primary output path to enable deinterlacer
3798 * mode : 1 for HD path, 2 for SD path
3799 */
3800void bapp_select_primary_output(bapp_t *p_app, int mode)
3801{
3802        if (!p_app) p_app = s_p_app;
3803
3804        bdisplay_set_deinterlacer(p_app->display,(mode==2)?1:0, true);
3805}
3806
3807/* select SCL's coefficient index
3808 * val : 1- 26 (1: soft -> 26: sharp
3809 */
3810void bapp_select_scaler_coefficient(bapp_t *p_app, bool horizontal, int output, int coeff_idx)
3811{
3812        if (!p_app) p_app = s_p_app;
3813        if (coeff_idx < 1 || coeff_idx > 26) 
3814        {
3815                BDBG_WRN(("Invalid SCL coefficient index : %d", coeff_idx));
3816                return;
3817        }
3818        bdisplay_set_coefficient_index(p_app->display, horizontal, output, coeff_idx);
3819}
3820
3821#ifdef OOB_TUNER_SUPPORT
3822
3823/*
3824 * Set OOB flag so that the message filter will get message from OOB input instead
3825 */
3826void bapp_set_oob_flag(int oob)
3827{
3828}
3829#endif
3830void bapp_get_avl_settings(int *target, int *low, int *boost)
3831{
3832        baudio_decode_config aconfig;
3833        bapp_t *p_app = (bapp_t *)s_p_app;
3834        baudio_decode_get_config(p_app->audio, &aconfig);
3835        *target = aconfig.avl_target/100;
3836        *low = aconfig.avl_lowerbound/100;
3837        *boost = aconfig.avl_fixedboost/100;
3838}
3839
3840void bapp_set_avl_settings(int target, int low, int boost)
3841{
3842        baudio_decode_config aconfig;
3843        bapp_t *p_app = (bapp_t *)s_p_app;
3844
3845        baudio_decode_get_config(p_app->audio, &aconfig);
3846        aconfig.avl_fixedboost = boost*100;
3847        aconfig.avl_target = target*100;
3848        aconfig.avl_lowerbound = low*100;
3849        baudio_decode_set_config(p_app->audio, &aconfig);
3850}
3851
3852/*
3853 * validation of current channel
3854 *
3855 * Return:
3856 *      pointer to a structure with channel information
3857 *      NULL if invalid
3858 */
3859bapp_ch_t *bapp_is_channel_valid(bapp_t *p_app)
3860{
3861        if (p_app->settings.num_channels < 1 || p_app->cur_ch_num >= p_app->settings.num_channels)
3862                return NULL;
3863
3864        return &p_app->settings.ch[p_app->cur_ch_num];
3865}
3866
3867/*
3868 * Summary:
3869 *     Set closed captions CS options
3870 *     Description:
3871 *         Set closed captions CS options
3872 */
3873void bapp_set_captions_options(bapp_t *p_app)
3874{
3875        BDBG_MSG(("%s current %d, new %d", __FUNCTION__,p_app->settings.dcc.captions_basic,p_app->captions_basic));
3876        if (p_app->captions_basic != p_app->settings.dcc.captions_basic)
3877        {
3878                p_app->settings.dcc.captions_basic = p_app->captions_basic;
3879                p_app->settings_dirty |= DIRTY_DCC;
3880                /* set it */
3881                bapp_set_wide_aspect_ratio(p_app);
3882#ifdef ACB612
3883#ifdef CONFIG_EIA_708
3884                bapp_eia708_set_cc_service(p_app->eia708, 1 , p_app->settings.dcc.captions_basic);
3885#endif
3886#endif         
3887        }
3888}
3889
3890/*
3891 * Summary:                             
3892 *     Set AspectRatio option selected from IR AR button
3893 *     Description:                     
3894 *         Set AspectRatio option selected from IR AR button
3895 */                                     
3896void bapp_set_ar_options(bapp_t *p_app)
3897{
3898        BDBG_WRN(("%s current %d, new %d", __FUNCTION__,p_app->settings.sd_options,p_app->sd_options));
3899        if (p_app->sd_options != p_app->settings.sd_options)
3900        {                           
3901                bdisplay_settings display_settings;     
3902                bdisplay_get(p_app->display,&display_settings);
3903                display_settings.sd_options = p_app->sd_options;
3904                bdisplay_set(p_app->display,&display_settings);
3905                p_app->settings.sd_options = display_settings.sd_options;
3906                p_app->settings_dirty |= DIRTY_MISC;
3907        }                           
3908}                               
3909
3910/*
3911 * enable or disable AVL
3912 *
3913 * Return:
3914 *      None.
3915 */
3916void bapp_P_enable_avl(bapp_t *p_app, bool enable)
3917{
3918        baudio_decode_config aconfig;
3919
3920        baudio_decode_get_config(p_app->audio, &aconfig);
3921        if (aconfig.avl != enable) {
3922                aconfig.avl = enable;
3923                baudio_decode_set_config(p_app->audio, &aconfig);
3924        }
3925}
3926
3927/*
3928 * enable or disable AVL
3929 *
3930 * Return:
3931 *      None.
3932 */
3933void bapp_enable_avl(bool enable)
3934{
3935        if (s_p_app) {
3936                bapp_P_enable_avl(s_p_app, enable);
3937        }
3938}
3939
3940/*
3941 * get application instance pointer
3942 *
3943 * Return:
3944 *  application instance pointer
3945 */
3946bapp_t *bapp_get_app_instance(void)
3947{
3948        BDBG_ASSERT(s_p_app);
3949        return s_p_app;
3950}
3951
3952/*
3953 * return current wide_aspect_ratio on current service if defined
3954 */
3955int bapp_get_wide_aspect_ratio_cb(void)
3956{
3957        bapp_t *p_app = s_p_app;
3958
3959        if (p_app) {
3960                return p_app->wide_aspect_ratio;
3961        }
3962        /* default not wide_aspect_ratio */
3963        return 0;
3964}
3965
3966/*
3967 * set current wide_aspct_ratio based on currnet channel's service number
3968 */
3969void bapp_set_wide_aspect_ratio(bapp_t *p_app)
3970{
3971        bool wide_aspect_ratio;
3972
3973        if (chm_has_valid_cc_service(&p_app->chm, &wide_aspect_ratio)) {
3974                p_app->wide_aspect_ratio = wide_aspect_ratio;
3975        }
3976        else   
3977                p_app->wide_aspect_ratio = 0;
3978}
3979
3980
3981void aov_scan_psi_a_freq(uint32_t freq_khz)
3982{
3983        if (s_p_app) {
3984#ifdef TUNER_DEBUG
3985                if (chm_scan_psi_a_freq(&s_p_app->chm, freq_khz) > 0) {
3986                        s_p_app->chm.force_tune = true;
3987                        bapp_tune(s_p_app);
3988                        s_p_app->settings_dirty |= DIRTY_MISC;
3989                }
3990#endif
3991        }
3992}
3993
3994
3995#ifdef TUNER_DEBUG
3996void bapp_scan_psi_a_freq(uint32_t freq_khz)
3997{
3998        if (s_p_app) {
3999                if (chm_scan_psi_a_freq(&s_p_app->chm, freq_khz) > 0) {
4000                        s_p_app->chm.force_tune = true;
4001                        bapp_tune(s_p_app);
4002                        s_p_app->settings_dirty |= DIRTY_MISC;
4003                }
4004        }
4005}
4006
4007void bapp_get_tuner_status(void)
4008{
4009        if (s_p_app) {
4010                p_app->tuner_status.cancal_callback = NULL;
4011                btuner_get_status(s_p_app->chm.tuner,&s_p_app->tuner_status);
4012
4013                BDBG_WRN(("lock=%d", s_p_app->tuner_status.lock));
4014                BDBG_WRN(("fecLock=%d", s_p_app->tuner_status.fecLock));
4015                BDBG_WRN(("snr=%d", s_p_app->tuner_status.snr));
4016                BDBG_WRN(("goodRsBlockCount=%d", s_p_app->tuner_status.goodRsBlockCount));
4017                BDBG_WRN(("berRawCount=%d", s_p_app->tuner_status.berRawCount));
4018                BDBG_WRN(("agcIntLevel=%d", s_p_app->tuner_status.agcIntLevel));
4019                BDBG_WRN(("postRsBER=%d", s_p_app->tuner_status.postRsBER));
4020                BDBG_WRN(("correctedCount=%d", s_p_app->tuner_status.correctedCount));
4021                BDBG_WRN(("uncorrectedCount=%d", s_p_app->tuner_status.uncorrectedCount));
4022                BDBG_WRN(("resyncCount=%d", s_p_app->tuner_status.resyncCount));
4023                BDBG_WRN(("mode=%d", s_p_app->tuner_status.mode));
4024        }
4025}
4026#endif
4027
4028/*janzy@20121108,add bapp_brfm_set_ch3*/
4029void bapp_brfm_set_ch3(bool ch)
4030{
4031        brfm_set_ch3(s_p_app->p_rfm, ch);
4032        return;
4033}
4034
4035/*janzy@20121108,add set Rf Output*/
4036void bapp_bdisplay_setRfOutput(bool isOutput)
4037{
4038        bdisplay_output_rf_enable(s_p_app->display,isOutput);
4039        return;
4040}
4041
4042/*janzy@20121109,add bapp_audio_1k_TONE*/
4043void bapp_audio_1k_TONE(void)
4044{
4045#ifdef MERGE_20121115
4046        bscreen_audio_1k_TONE();
4047#endif
4048        return;
4049}
4050
4051/*janzy@20121113,audio,video start/stop ctrl begin*/
4052void bapp_audio_stop(void)
4053{
4054        if (s_p_app->audio)
4055                baudio_decode_stop(s_p_app->audio);
4056
4057        return;
4058}
4059
4060void bapp_video_stop(void)
4061{
4062        if (s_p_app->decode)
4063                bdecode_stop(s_p_app->decode);
4064        return;
4065}
4066
4067void bapp_AV_start(unsigned int vid,unsigned int aud,unsigned int pcr)
4068{
4069        /*RLQ*/
4070#if 0
4071        aov_dbg_print1();
4072#endif
4073        if (s_p_app->settings.av_mute)
4074                return;
4075
4076        /* remember previous channel so that we can go back, e.g. EAS turned */
4077        s_p_app->prev_ch = s_p_app->cur_ch;
4078
4079        s_p_app->settings.ch[s_p_app->cur_ch_num].video_pid = vid;
4080        s_p_app->settings.ch[s_p_app->cur_ch_num].pcr_pid = pcr;
4081        s_p_app->settings.ch[s_p_app->cur_ch_num].audio_pid[0] = aud;
4082
4083        printf("cur_ch_num = %d\n",s_p_app->cur_ch_num);
4084        printf("voide PID = %d\n",s_p_app->settings.ch[s_p_app->cur_ch_num].video_pid);
4085        printf("audio PID = %d\n",s_p_app->settings.ch[s_p_app->cur_ch_num].audio_pid[0]);
4086        printf("pcr    PID = %d\n",s_p_app->settings.ch[s_p_app->cur_ch_num].pcr_pid);
4087
4088
4089        if (bos_acquire_mutex(&(s_p_app->flash_mutex), 250) != b_ok) 
4090        {
4091                printf("%s:%d mutex timeout\n", __FUNCTION__, __LINE__);
4092                return;
4093        }
4094
4095        bast_channel_map_save(s_p_app);
4096
4097        bos_release_mutex(&(s_p_app->flash_mutex));
4098
4099
4100        /* set current channel */
4101        s_p_app->cur_ch = s_p_app->settings.ch[s_p_app->cur_ch_num];
4102        if (s_p_app->decoding)
4103        {
4104                /* TODO */
4105        }
4106
4107        s_p_app->lock = false;
4108        s_p_app->power_level = 0;
4109
4110        s_p_app->tune_cmd.cmd_id = eCHM_TUNE;
4111        s_p_app->tune_cmd.type = eCHM_CURRENT;
4112        chm_cmd(&s_p_app->chm,(chm_cmd_event_t*)&s_p_app->tune_cmd);
4113        s_p_app->decoding         = true;
4114        s_p_app->last_tune_tick   = bos_getticks();
4115
4116        return;
4117}
4118
4119/*janzy@20121113,add ColorBars*/
4120void bapp_Set_ColorBars(bool enable)
4121{
4122        uint16_t temp_w,tmp_h,tmp_y,tmp_X;
4123        double numb1,numb2,numb3;
4124
4125        bapp_sync(s_p_app);
4126
4127        if (enable)
4128        {
4129                bgfx_fill_rect(&s_p_app->surf,0                 ,0      ,eWIDTH         ,eHEIGHT,0XFF131313);
4130                /* x, y,w,h*/
4131                temp_w = (uint16_t)(eWIDTH/7)+1;
4132                numb1 = 325.0;
4133                numb2 = 480.0;
4134                numb3 = (numb1/numb2)*eHEIGHT;
4135                tmp_h = (uint16_t)numb3;
4136
4137                bgfx_fill_rect(&s_p_app->surf,temp_w*0  ,0      ,temp_w ,tmp_h,0xFFCCCCCC);
4138                bgfx_fill_rect(&s_p_app->surf,temp_w*1  ,0      ,temp_w ,tmp_h,0XFFFFFF00);
4139                bgfx_fill_rect(&s_p_app->surf,temp_w*2  ,0      ,temp_w ,tmp_h,0XFF00FFFF);
4140                bgfx_fill_rect(&s_p_app->surf,temp_w*3  ,0      ,temp_w ,tmp_h,0XFF00FF00);
4141                bgfx_fill_rect(&s_p_app->surf,temp_w*4  ,0      ,temp_w ,tmp_h,0XFFFF00FF);
4142                bgfx_fill_rect(&s_p_app->surf,temp_w*5  ,0      ,temp_w ,tmp_h,0XFFFF0000);
4143                bgfx_fill_rect(&s_p_app->surf,temp_w*6  ,0      ,temp_w ,tmp_h,0XFF0000FF);
4144                tmp_y = tmp_h;
4145                numb1 = 40.0;
4146                numb2 = 480.0;
4147                numb3 = (numb1/numb2)*eHEIGHT;
4148                tmp_h = (uint16_t)numb3;
4149
4150                bgfx_fill_rect(&s_p_app->surf,temp_w*0  ,tmp_y  ,temp_w ,tmp_h,0xFF0000FF);
4151                bgfx_fill_rect(&s_p_app->surf,temp_w*1  ,tmp_y  ,temp_w ,tmp_h,0XFF131313);
4152                bgfx_fill_rect(&s_p_app->surf,temp_w*2  ,tmp_y  ,temp_w ,tmp_h,0XFFFF00FF);
4153                bgfx_fill_rect(&s_p_app->surf,temp_w*3  ,tmp_y  ,temp_w ,tmp_h,0XFF131313);
4154                bgfx_fill_rect(&s_p_app->surf,temp_w*4  ,tmp_y  ,temp_w ,tmp_h,0XFF00FFFF);
4155                bgfx_fill_rect(&s_p_app->surf,temp_w*5  ,tmp_y  ,temp_w ,tmp_h,0XFF131313);
4156                bgfx_fill_rect(&s_p_app->surf,temp_w*6  ,tmp_y  ,temp_w ,tmp_h,0XFFCCCCCC);
4157
4158                tmp_y = tmp_y+tmp_h;
4159                temp_w = (uint16_t)(eWIDTH/7)+1;
4160                numb1 = (double)temp_w;
4161                numb1 = (numb1*5)/4;
4162                temp_w = (uint16_t)numb1+1;
4163
4164                bgfx_fill_rect(&s_p_app->surf,temp_w*0  ,tmp_y  ,temp_w ,eHEIGHT,0xFF083E59);
4165                bgfx_fill_rect(&s_p_app->surf,temp_w*1  ,tmp_y  ,temp_w ,eHEIGHT,0XFFFFFFFF);
4166                bgfx_fill_rect(&s_p_app->surf,temp_w*2  ,tmp_y  ,temp_w ,eHEIGHT,0XFF3A0078);
4167                bgfx_fill_rect(&s_p_app->surf,temp_w*3  ,tmp_y  ,temp_w ,eHEIGHT,0XFF131313);
4168
4169                tmp_X = temp_w*4;
4170                temp_w = (uint16_t)(((eWIDTH/7)+1)/3);
4171
4172                bgfx_fill_rect(&s_p_app->surf,tmp_X+temp_w*0    ,tmp_y  ,temp_w ,eHEIGHT,0xFF000000);
4173                bgfx_fill_rect(&s_p_app->surf,tmp_X+temp_w*1    ,tmp_y  ,temp_w ,eHEIGHT,0XFF131313);
4174                bgfx_fill_rect(&s_p_app->surf,tmp_X+temp_w*2    ,tmp_y  ,temp_w ,eHEIGHT,0XFF262626);
4175        }
4176        else 
4177        {
4178                bgfx_fill_rect(&s_p_app->surf,0 ,0,eWIDTH,eHEIGHT,0);
4179        }
4180
4181        bapp_flush_screen(s_p_app);     
4182        return;
4183}
4184
4185
4186void bapp_do_exit()/*janzy@20121115,OSD TimeOut*/
4187{
4188        aov_Set_Button_CHUpDown(3);
4189        return;
4190}
4191
4192bool bapp_is_dolby_type(bapp_t *p_app)
4193{
4194        bapp_ch_t *pch;
4195
4196        pch = &p_app->settings.ch[p_app->cur_ch_num];
4197        if ((BAVC_AudioCompressionStd_eAc3 == pch->audio_type[pch->cur_audio]) || 
4198                        (BAVC_AudioCompressionStd_eAc3Plus == pch->audio_type[pch->cur_audio])) {
4199                return true;
4200        }
4201        return false;
4202}
4203
4204/*end*/
Note: See TracBrowser for help on using the repository browser.