source: svn/branches/kctv/newcon3bcm2_21bu/nexus/app/nanotv/bapp.c @ 43

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 97.5 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#ifndef LINUX
26        #include "bos.h"
27        #include "ministd.h"
28        #include "cache_util.h"
29        #define  GETTIMEOFDAY(tv)   gettimeofday(tv)
30#else
31        #include <sys/cachectl.h>
32        #define  GETTIMEOFDAY(tv)   gettimeofday(tv,NULL)
33#endif
34#include "bchp_cce_prim.h"
35#include "bchp_hifidac_ctrl0.h"
36#if (BCHP_CHIP != 3543)
37#if (BCHP_CHIP == 7002)
38#else
39        #include "bchp_aud_adp0.h"
40#endif
41#endif
42#if (BCHP_CHIP == 7002)
43#else
44#include "bchp_xpt_cfg.h"
45#endif
46#include "bchp_sun_top_ctrl.h"
47#include "bchp_sun_l2.h"
48#include "bsmart.h"
49
50#include "bchp_memc_ddr.h"
51#include "bchp_timer.h"
52#if (BCHP_CHIP == 3543)
53        #include "bchp_memc_core.h"
54        #include "bchp_aio_misc.h"
55#endif
56#include "bchp_pcm.h"
57
58BDBG_MODULE(bapp);              /* Register software module with debug interface */
59
60
61#define BAPP_VCHIP_TIMEOUT            (7000)      /* Milliseconds */
62#define BAPP_RATINGS_EVAL_DELAY       (500)       /* Milliseconds */
63#define DEFAULT_VOLUME                                  100
64#define DEFAULT_RFM_VOLUME                              70
65
66#define BAPP_VCHIP_MSG                                  BDBG_WRN
67#define TIME_APP_DRAWING
68static bgfx_font_t  s_font[eFONT_SIZE_MAX];
69
70
71typedef enum rsys_t
72{
73        eRS_MPA,
74        eRS_US,
75        eRS_MPA_OLD,
76        eRS_CANADIAN_ENGLISH,
77        eRS_CANADIAN_FRENCH,
78        eRS_RESERVED_0,
79        eRS_RESERVED_1
80}rsys_t;
81const static unsigned int s_remote_type_map[] =
82{
83        5,
84        4,
85        6,
86        0
87};
88
89const static char *s_rsys_name[] =
90{
91        "MPA",
92        "TV",
93        "MPA",
94        "CE",
95        "CF",
96        "R0",
97        "R1"
98};
99bapp_t *s_p_app = NULL;
100
101static bscreen_t g_screens[] =
102{  /* title_text_id                    desc_text_id                          help_text_id      top_banner_height                               num_buttons                         idle_timeout                          p_button_array                  (* draw)()                     (* handle_event)()             local_state */
103        { 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},
104        { 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},
105        { eTEXT_PICTURE_MENU,          eTEXT_PICTURE_MENU_DESC,          eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_2_LINE,           0, 0, g_buttons_picture_num,          SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_picture,          bscreen_default_draw,          screen_picture_event,          0},
106        { 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_NULL, g_buttons_sound,            bscreen_default_draw,          screen_sound_event,            0},
107    { 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},
108        { eTEXT_ANTENNA_MENU,          eTEXT_ANTENNA_MENU_DESC,          eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_antenna_draw,          screen_antenna_event,          0},
109    { 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},
110#if 0
111    { eTEXT_CAPTIONS_ON_OFF_MENU,      eTEXT_CAPTIONS_ON_OFF_MENU_DESC,      eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_on_off_num,      SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_on_off,      bscreen_default_draw,          screen_captions_on_off_event,       0},
112    { eTEXT_CAPTIONS_BASIC_MENU,       eTEXT_CAPTIONS_BASIC_MENU_DESC,       eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_LINE,           0, 0, g_buttons_captions_basic_num,       SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_captions_basic,       bscreen_default_draw,          screen_captions_basic_event,        0},
113    { eTEXT_CAPTIONS_ADVANCED_MENU,    eTEXT_CAPTIONS_ADVANCED_MENU_DESC,    eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_1_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},
114#endif
115        { 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},
116    { 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},
117    { 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},
118    { 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},
119    { 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},
120    { 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},
121    { 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},
122    { 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},
123    { 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},
124    { 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},
125    { 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},
126    { 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},
127        { 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},
128#ifdef CONFIG_EIA_708
129        { 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},
130#else   
131        { 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},
132#endif
133        { 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},
134        { eTEXT_WIZ_SMART_CH_SCAN_MENU,    eTEXT_WIZ_SMART_CH_SCAN_MENU_DESC,    eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_3_LINE,           0, 0, g_buttons_smart_ch_scan_num,        SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_smart_ch_scan,        bscreen_wiz_ch_scan_draw,      screen_ch_scan_event,          0},
135        { 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},
136        { 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},
137        { 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},
138    { 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},
139        { 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},
140        { eTEXT_WIZ_SMART_CH_SCAN_MENU,    eTEXT_WIZ_SMART_CH_SCAN_MENU_DESC,    eTEXT_MENU_HELP2, eMENU_TITLE_AREA_HEIGHT_3_LINE,           0, 0, g_buttons_wiz_smart_ch_scan_num,    SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, g_buttons_wiz_smart_ch_scan,    bscreen_wiz_ch_scan_draw,      screen_wiz_ch_scan_event,      0},
141        { 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},
142        { 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},
143        { 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},
144        { 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},
145        { 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},
146        { 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},
147        { 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},
148        { 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},
149        { eTEXT_RATINGS_TV_MENU,           eTEXT_RATINGS_TV_MENU_DESC,           eTEXT_MENU_HELP10,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},
150        { 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},
151        { 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},
152        { 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},
153        { 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},
154        { 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},
155        { 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},
156        { 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},
157        { 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},
158        { 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},
159        { 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},
160        { 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},
161        { 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},
162        { 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},
163        { 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},
164    { eTEXT_GUIDE_TITLE,               eTEXT_MAX,                            eTEXT_MENU_HELP11,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},
165        { 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},
166        { eTEXT_MAX,                   eTEXT_MAX,                        eTEXT_MAX,        0,                                        0, 0, 0,                              0,                      eSCREEN_NULL, 0,                          bscreen_power_off_draw,        screen_power_off_event,        0},
167        { 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},
168        { eTEXT_MAX,                   eTEXT_MAX,                        eTEXT_MAX,        0,                                        0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_status_draw,           bscreen_status_event,          0},
169#ifdef  CONFIG_DTA_CABLE
170        { eTEXT_MAX,                   eTEXT_MAX,                        eTEXT_MAX,        0,                                        0, 0, 0,                              SCREEN_DEFAULT_TIMEOUT, eSCREEN_NULL, 0,                          bscreen_debug_draw,            bscreen_debug_event,           0},
171#endif
172};                                                                                                                                                                 
173
174const unsigned char g_screens_num = sizeof(g_screens)/sizeof(g_screens[0]);
175
176#if (DEF_CH_MAP == 3) /* default channel production default channel map */
177        #warning "DEF_CH_MAP = 3"
178static const bapp_ch_t s_def_ch_map[] =
179{
180#if 0
181        {14,1,12,1,0x21,0x21,1,0,{0x24,0,0},{0x0046, 0x0065, 0x0067, 0x0084, 0x0045, 0x0049, 0x0052},0},
182#else
183        {18,1,16,1,0x21,0x21,3,0,{0x24,0x25,0},{0x004B, 0x0054, 0x004C, 0x0041, 0x002D, 0x0044, 0x0054},0},
184#endif
185        {2,1,0,1,0x21,0x21,1,0,{0x24,0,0},{0x0046, 0x0065, 0x0067, 0x0084, 0x0045, 0x0048, 0x0050},0},
186        {69,1,67,1,0x21,0x21,1,0,{0x24,0,0},{0x0046, 0x0065, 0x0067, 0x0084, 0x0045, 0x0054, 0x0057},0},
187};
188
189const unsigned char g_def_ch_num = sizeof(s_def_ch_map)/sizeof(s_def_ch_map[0]);
190#elif (DEF_CH_MAP == 2) /* default channel map in San Jose for testing purposes only */
191        #warning "DEF_CH_MAP = 2"
192static const bapp_ch_t s_def_ch_map[] =
193{
194        {2,1,54,1,49,49,1,0,{52,0,0},{0x004b, 0x0054, 0x0056, 0x0055, 0x002d, 0x0044, 0x0054},0},
195        {4,1,55,1,49,49,1,0,{52,0,0},{0x004b, 0x0052, 0x004f, 0x004e, 0x002d, 0x0053, 0x0044},0},
196        {4,2,55,1,65,65,1,0,{68,0,0},{0x004b, 0x0052, 0x004f, 0x004e, 0x002d, 0x0048, 0x0044},0},
197        {5,1,27,0,49,49,1,0,{52,0,0},{0x004b, 0x0050, 0x0049, 0x0058, 0x002d, 0x0048, 0x0044},0},
198        {7,1,22,0,49,49,1,0,{52,0,0},{0x004b, 0x0047, 0x004f, 0x002d, 0x0044, 0x0054, 0x0020},0},
199        {7,2,22,0,65,65,1,0,{68,0,0},{0x004b, 0x0047, 0x004f, 0x002d, 0x0044, 0x0054, 0x0020},0},
200        {7,3,22,0,81,81,1,0,{84,0,0},{0x004b, 0x0047, 0x004f, 0x002d, 0x0044, 0x0054, 0x0020},0},
201        {9,1,28,0,49,49,1,0,{51,0,0},{0x004b, 0x0051, 0x0045, 0x0044, 0x002d, 0x0048, 0x0044},0},
202        {9,2,28,0,65,65,5,0,{67,0,68},{0x0045, 0x004e, 0x0043, 0x004f, 0x0052, 0x0045, 0x0000},0},
203        {9,3,28,0,81,81,5,0,{83,0,84},{0x0057, 0x004f, 0x0052, 0x004c, 0x0044, 0x0000, 0x0000},0},
204        {9,4,28,0,97,97,5,0,{99,0,100},{0x004c, 0x0049, 0x0046, 0x0045, 0x0000, 0x0000, 0x0000},0},
205        {9,5,28,0,113,113,5,0,{115,0,116},{0x004b, 0x0049, 0x0044, 0x0053, 0x0000, 0x0000, 0x0000},0},
206        {11,1,10,0,49,49,1,0,{52,0,0},{0x004b, 0x004e, 0x0054, 0x0056, 0x002d, 0x0048, 0x0044},0},
207        {11,2,10,0,65,65,1,0,{68,0,0},{0x004e, 0x0042, 0x0043, 0x0020, 0x0057, 0x0065, 0x0061},0},
208        {20,1,17,0,49,49,1,0,{52,0,0},{0x004b, 0x0042, 0x0057, 0x0042, 0x002d, 0x0048, 0x0044},0},
209        {20,2,17,0,65,65,1,0,{68,0,0},{0x004b, 0x0042, 0x0057, 0x0042, 0x002d, 0x0053, 0x0044},0},
210        {26,1,25,0,49,49,1,0,{52,0,0},{0x004b, 0x0054, 0x0053, 0x0046, 0x002d, 0x0044, 0x0031},0},
211        {26,2,25,0,49,49,1,0,{68,0,0},{0x004b, 0x0054, 0x0053, 0x0046, 0x002d, 0x0044, 0x0032},0},
212        {32,1,31,0,49,49,1,0,{52,0,0},{0x004b, 0x004d, 0x0054, 0x0050, 0x002d, 0x0044, 0x0031},0},
213        {32,2,31,0,65,65,1,0,{68,0,0},{0x004b, 0x004d, 0x0054, 0x0050, 0x002d, 0x0044, 0x0032},0},
214        {32,3,31,0,81,81,1,0,{84,0,0},{0x004b, 0x004d, 0x0054, 0x0050, 0x002d, 0x0044, 0x0033},0},
215        {32,5,31,0,97,97,1,0,{100,0,0},{0x004b, 0x004d, 0x0054, 0x0050, 0x002d, 0x0044, 0x0035},0},
216        {36,1,50,0,49,49,1,0,{52,0,0},{0x004b, 0x0049, 0x0043, 0x0055, 0x002d, 0x0044, 0x0054},0},
217        {36,2,50,0,65,65,1,0,{68,0,0},{0x004b, 0x0054, 0x0056, 0x004e, 0x002d, 0x0044, 0x0054},0},
218        {38,1,37,0,49,49,1,0,{52,0,0},{0x004b, 0x0043, 0x004e, 0x0053, 0x0000, 0x0000, 0x0000},0},
219        {43,1,41,0,33,33,1,0,{36,0,0},{0x004b, 0x0043, 0x0053, 0x004d, 0x0020, 0x0054, 0x0056},0},
220        {43,2,41,0,49,49,1,0,{52,0,0},{0x004b, 0x0043, 0x0053, 0x004d, 0x004d, 0x0048, 0x005a},0},
221        {43,3,41,0,65,65,1,0,{68,0,0},{0x004a, 0x0061, 0x007a, 0x007a, 0x0020, 0x0054, 0x0056},0},
222        {44,1,43,0,49,49,1,0,{52,0,0},{0x004b, 0x0042, 0x0043, 0x0057, 0x002d, 0x0048, 0x0044},0},
223        {48,1,47,0,49,49,1,0,{52,0,0},{0x004b, 0x0053, 0x0054, 0x0053, 0x002d, 0x0044, 0x0054},0},
224        {54,1,48,0,49,49,1,0,{51,0,0},{0x004b, 0x0054, 0x0045, 0x0048, 0x002d, 0x0048, 0x0044},0},
225        {54,2,48,0,65,65,1,0,{67,0,0},{0x0056, 0x002d, 0x006d, 0x0065, 0x0000, 0x0000, 0x0000},0},
226        {54,3,48,0,81,81,1,0,{83,0,0},{0x004b, 0x0054, 0x0045, 0x0048, 0x002d, 0x0053, 0x0044},0},
227        {65,1,39,0,49,49,1,0,{52,0,0},{0x0069, 0x006f, 0x006e, 0x0000, 0x0000, 0x0000, 0x0000},0},
228        {65,2,39,0,65,65,3,0,{68,69,0},{0x0071, 0x0075, 0x0062, 0x006f, 0x0000, 0x0000, 0x0000},0},
229        {65,3,39,0,81,81,1,0,{84,0,0},{0x0069, 0x006f, 0x006e, 0x0020, 0x0045, 0x0000, 0x0000},0},
230        {65,4,39,0,97,97,1,0,{100,0,0},{0x0057, 0x006f, 0x0072, 0x0073, 0x0068, 0x0069, 0x0070},0},
231        {66,1,32,0,49,49,2,0,{0,52,0},{0x004b, 0x0046, 0x0053, 0x0046, 0x0020, 0x0044, 0x0054},0},
232        {66,2,32,0,65,65,2,0,{0,68,0},{0x004b, 0x0044, 0x0054, 0x0056, 0x002d, 0x0044, 0x0054},0},
233        {68,1,45,0,49,49,1,0,{52,0,0},{0x004b, 0x0054, 0x004c, 0x004e, 0x002d, 0x0044, 0x0054},0},
234};
235const unsigned char g_def_ch_num = sizeof(s_def_ch_map)/sizeof(s_def_ch_map[0]);
236#elif (DEF_CH_MAP == 1) /* default channel map in San Diego for testing purposes only */
237        #warning "DEF_CH_MAP = 1"
238static const bapp_ch_t s_def_ch_map[] =
239{
240        {8,1,53,0,49,49,1,0,{52,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
241        {10,1,23,0,49,49,1,0,{52,0,0},{0x004b, 0x0047, 0x0054, 0x0056, 0x002d, 0x0044, 0x0054},0},
242        {15,1,28,0,49,49,1,0,{0,0,0},{0x004b, 0x0050, 0x0042, 0x0053, 0x002d, 0x0048, 0x0044},0},
243        {15,2,28,0,65,65,1,0,{0,0,0},{0x0056, 0x002d, 0x006d, 0x0065, 0x0000, 0x0000, 0x0000},0},
244        {39,1,38,0,49,49,1,0,{52,0,0},{0x004b, 0x004e, 0x0053, 0x0044, 0x0020, 0x0048, 0x0044},0},
245        {39,2,38,0,65,65,1,0,{68,0,0},{0x0057, 0x0058, 0x0020, 0x0050, 0x006c, 0x0075, 0x0073},0},
246        {51,1,16,0,49,49,1,0,{52,0,0},{0x004b, 0x0055, 0x0053, 0x0049, 0x002d, 0x0048, 0x0044},0},
247        {69,1,17,0,49,49,5,0,{52,53,0},{0x004b, 0x0053, 0x0057, 0x0042, 0x002d, 0x0044, 0x0054},0},
248        {69,3,17,0,65,65,1,0,{68,0,0},{0x0054, 0x0075, 0x0062, 0x0065, 0x0000, 0x0000, 0x0000},0},
249};
250const unsigned char g_def_ch_num = sizeof(s_def_ch_map)/sizeof(s_def_ch_map[0]);
251#elif (DEF_CH_MAP == 4) /* default channel map in San Diego for testing purposes only */
252        #warning "DEF_CH_MAP = 4"
253static const bapp_ch_t s_def_ch_map[] =
254{
255        {2,1,0,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
256        {3,1,1,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
257        {4,1,2,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
258        {5,1,3,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
259        {6,1,4,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
260        {7,1,5,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
261        {8,1,6,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
262        {9,1,7,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
263        {10,1,8,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
264        {11,1,9,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
265        {12,1,10,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
266        {13,1,11,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
267        {14,1,12,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
268        {15,1,13,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
269        {16,1,14,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
270        {17,1,15,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
271        {18,1,16,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
272        {19,1,17,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
273        {20,1,18,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
274        {21,1,19,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
275        {22,1,20,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
276        {23,1,21,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
277        {24,1,22,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
278        {25,1,23,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
279        {26,1,24,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
280        {27,1,25,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
281        {28,1,26,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
282        {29,1,27,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
283        {30,1,28,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
284        {31,1,29,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
285        {32,1,30,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
286        {33,1,31,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
287        {34,1,32,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
288        {35,1,33,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
289        {36,1,34,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
290        {37,1,35,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
291        {38,1,36,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
292        {39,1,37,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
293        {40,1,38,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
294        {41,1,39,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
295        {42,1,40,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
296        {43,1,41,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
297        {44,1,42,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
298        {45,1,43,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
299        {46,1,44,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
300        {47,1,45,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
301        {48,1,46,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
302        {49,1,47,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
303        {50,1,48,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
304        {51,1,49,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
305        {52,1,50,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
306        {53,1,51,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
307        {54,1,52,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
308        {55,1,53,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
309        {56,1,54,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
310        {57,1,55,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
311        {58,1,56,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
312        {59,1,57,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
313        {60,1,58,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
314        {61,1,59,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
315        {62,1,60,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
316        {63,1,61,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
317        {64,1,62,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
318        {65,1,63,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
319        {66,1,64,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
320        {67,1,65,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
321        {68,1,66,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
322        {69,1,67,1,0,0,1,0,{0,0,0},{0x004b, 0x0046, 0x004d, 0x0042, 0x002d, 0x0044, 0x0054},0},
323};
324const unsigned char g_def_ch_num = sizeof(s_def_ch_map)/sizeof(s_def_ch_map[0]);
325#endif
326
327#define BAPP_TV_RATING_STR_NUM  8
328static const char *bapp_tv_rating_str[BAPP_TV_RATING_STR_NUM] =
329{
330        "",     /* unrated */
331        "TV-Y",
332        "TV-Y7",
333        "TV-G",
334        "TV-PG",
335        "TV-14",
336        "TV-MA",
337        ""      /* unrated */
338};
339
340/* LUT used to translate from user defined tv  limit to canadian equivalent */
341static unsigned char tv_to_can_eng[8] = { 0, 1, 2, 3, 4, 5, 6, 0};
342static unsigned char tv_to_can_fra[8] = { 0, 2, 2, 2, 3, 4, 5, 0};
343
344#define BAPP_MPAA_RATING_STR_NUM        8
345static const char *bapp_mpa_rating_str[] =
346{
347        "",     /* unrated */
348        "G",
349        "PG",
350        "PG-13",
351        "R",
352        "NC-17",
353        "X",
354        "NR" /* Not Rated */
355};
356
357#define BAPP_CE_RATING_STR_NUM  8
358static const char *bapp_ce_rating_str[] =
359{
360        "E",
361        "C",
362        "C8+",
363        "G",
364        "PG",
365        "14+",
366        "18+"
367        "",     /* invalid */
368};
369
370#define BAPP_CF_RATING_STR_NUM  8
371static const char *bapp_cf_rating_str[] =
372{
373        "E",
374        "G",
375        "8ans+",
376        "13ans+",
377        "16ans+",
378        "18ans+",
379        "",     /* invalid */
380        "",     /* invalid */
381};
382
383void bl_write(void)
384{
385}
386
387/*
388 * Flush cache
389 */
390
391void bapp_flush_screen(bapp_t *p_app)
392{
393        unsigned int *palette;
394        int width,height,pitch;
395        if (bgraphics_sync(p_app->graphics) == berr_timeout)
396        {
397                BDBG_WRN(("bgraphics_sync timeout, try again.\n" ));
398                if (bgraphics_sync(p_app->graphics) == berr_timeout)
399                {
400                        BDBG_ERR(("bgraphics_sync timeouted out again.\n" ));
401                }
402        }
403        bgraphics_get_framebuffer(p_app->graphics,(void**)&p_app->osd_mem,(unsigned int **)&palette,&width,&height,&pitch);
404        p_app->osd_mem_size = pitch * height;
405        p_app->width = width;
406        p_app->height = height;
407        p_app->surf.surface.buf = p_app->osd_mem;
408}
409
410
411/*
412 * Determine ratings system
413 */
414
415
416static rsys_t bapp_get_rsys(unsigned char c1, unsigned char c2)
417{
418        if ((c1 & 0x18) == 0x18) /* eRS_CANADIAN_ENGLISH - eRS_RESERVED_1 */
419        {
420                if (c1 & 0x20) /* eRS_CANADIAN_FRENCH or eRS_RESERVED_1 */
421                {
422                        if (c2 & 0x08)
423                                return eRS_RESERVED_1;
424                        else
425                                return eRS_CANADIAN_FRENCH;
426                } else
427                {
428                        if (c2 & 0x08)
429                                return eRS_RESERVED_0;
430                        else
431                                return eRS_CANADIAN_ENGLISH;
432                }
433        } else /* eRS_MPA - eRS_MPA_OLD */
434        {
435                if (c1 & 0x10)
436                        return eRS_MPA_OLD;
437                else if (c1 & 0x08)
438                        return eRS_US;
439                else
440                        return eRS_MPA;
441        }
442        return eRS_US;
443}
444
445/*
446 * Return 1 if MPA rating is exceeded
447 * Return 0 if MPA rating is not exceeded
448 * Return -1 on invalid rating or error
449 */
450
451static int bapp_mpa_block(unsigned char mpa_level,         /* MPA level 0 - 7 */
452                                                  unsigned char c1                                       /* xds 1 character */
453                                                 )
454{
455        c1 &= 0x7;
456
457        /* update rating string */
458        if (c1 < BAPP_MPAA_RATING_STR_NUM)
459                strcpy(s_p_app->prog_rating_str, bapp_mpa_rating_str[c1]);
460
461        if (c1 == 0)
462                return -1; /* level 0 rating not applicable */
463
464        return(c1 >= mpa_level) ? 1 : 0;
465}
466
467/*
468 * Return 1 if Canadian English rating is exceeded
469 * Return 0 if MPA rating is not exceeded
470 * Return -1 on invalid rating or error
471 */
472
473static int bapp_CE_block(unsigned char CE_level,   /* Canadian English level 0 - 7 */
474                                                 unsigned char c2                                       /* xds 2 character */
475                                                )
476{
477        c2 &= 0x7;
478        if (c2 == 7)
479                return -1; /* level 7 rating is invalid */
480
481        /* update rating string */
482        if (c2 < BAPP_CE_RATING_STR_NUM)
483                strcpy(s_p_app->prog_rating_str, bapp_ce_rating_str[c2]);
484
485        if (c2 == 0)
486                return -1;
487        return(c2 >= CE_level) ? 1 : 0;
488}
489
490/*
491 * Return 1 if Canadian French rating is exceeded
492 * Return 0 if MPA rating is not exceeded
493 * Return -1 on invalid rating or error
494 */
495
496static int bapp_CF_block(unsigned char CF_level,   /* Canadian French level 0 - 7 */
497                                                 unsigned char c2                                       /* xds 2 character */
498                                                )
499{
500        c2 &= 0x7;
501        if ((c2 == 6) || (c2 == 7))
502                return -1; /* level 6 or 7 rating is invalid */
503
504        /* update rating string */
505        if (c2 < BAPP_CF_RATING_STR_NUM)
506                strcpy(s_p_app->prog_rating_str, bapp_cf_rating_str[c2]);
507
508        if (c2 == 0)
509                return -1;
510
511        return(c2 >= CF_level) ? 1 : 0;
512}
513
514/*
515 * Return 1 if US rating is exceeded
516 * Return 0 if MPA rating is not exceeded
517 * Return -1 on invalid rating or error
518 */
519
520static int bapp_US_block(unsigned char US_level,                   /* US level 0 - 7 */
521                                                 unsigned char mask,                     /* VSLD modifier mask */
522                                                 unsigned char c1,                               /* xds 1 character */
523                                                 unsigned char c2                                /* xds 2 character */
524                                                )
525{
526        unsigned char tmp_c2 = c2 & 0x7;
527        unsigned char c1_mask,c2_mask;
528        int slen;
529
530        c2_mask = (mask & 0xE) << 2;
531        c1_mask = (mask & 0x1) << 5;
532
533        /* update rating string */
534        if (tmp_c2 < BAPP_TV_RATING_STR_NUM)
535                strcpy(s_p_app->prog_rating_str, bapp_tv_rating_str[tmp_c2]);
536        else
537                s_p_app->prog_rating_str[0] = 0;
538
539        switch (tmp_c2)
540        {
541        case 2:
542                if (c2 & 0x20)
543                {
544                        slen = strlen(s_p_app->prog_rating_str);
545                        s_p_app->prog_rating_str[slen] = 'F';
546                        s_p_app->prog_rating_str[slen + 1] = 'V';
547                        s_p_app->prog_rating_str[slen + 2] = 0;
548                }
549                break;
550        case 4:
551        case 5:
552        case 6:
553                if (c2 & 0x20)
554                {
555                        slen = strlen(s_p_app->prog_rating_str);
556                        s_p_app->prog_rating_str[slen] = 'V';
557                        s_p_app->prog_rating_str[slen + 1] = 0;
558                }
559                if (c2 & 0x08)
560                {
561                        slen = strlen(s_p_app->prog_rating_str);
562                        s_p_app->prog_rating_str[slen] = 'L';
563                        s_p_app->prog_rating_str[slen + 1] = 0;
564                }
565                if (c2 & 0x10)
566                {
567                        slen = strlen(s_p_app->prog_rating_str);
568                        s_p_app->prog_rating_str[slen] = 'S';
569                        s_p_app->prog_rating_str[slen + 1] = 0;
570                }
571                if (tmp_c2 != 6)
572                {
573                        if (c1 & 0x20)
574                        {
575                                slen = strlen(s_p_app->prog_rating_str);
576                                s_p_app->prog_rating_str[slen] = 'D';
577                                s_p_app->prog_rating_str[slen + 1] = 0;
578                        }
579                }
580                break;
581        default:
582                break;
583        }
584
585        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 ));
586
587        if ((tmp_c2 == 0) || (tmp_c2 == 0x7))
588                return -1; /* level 0 and 7 ratings not applicable */
589
590        switch (US_level)
591        {
592        case 0:
593                return 0;
594        case 3:
595        case 1:return(tmp_c2 > US_level) ? 1 : 0;
596        case 2:
597                {
598                        if (tmp_c2 > US_level)
599                                return 1;
600                        else
601                                if ((tmp_c2 == US_level) &&     /* handle case where xds rating has no vsld modifier */
602                                        ((s_p_app->settings.ratings_tv >> screen_ratings_tv_xds2pos(US_level)) & (0 | (0x1))))
603                                return 1;
604                        else
605                                if ((tmp_c2 == US_level) && (c2 & (0x20 & c1_mask))) /* FV restriction */
606                                return 1;
607                }
608                break;
609        case 4:
610        case 5:
611                {
612                        if (tmp_c2 > US_level)
613                                return 1;
614                        else
615                                if ((tmp_c2 == US_level) &&     /* handle case where xds rating has no vsld modifier */
616                                        ((s_p_app->settings.ratings_tv >> screen_ratings_tv_xds2pos(US_level)) & (0 | (0x1))))
617                                return 1;
618                        else
619                                if ((tmp_c2 == US_level) && 
620                                        ((c2 & (0x38 & c2_mask)) || (c1 & (0x20 & c1_mask)))) /* VSLD restriction */
621                                return 1;
622                }
623                break;
624        case 6:
625                {
626                        if (tmp_c2 > US_level)
627                                return 1;
628                        else
629                                if ((tmp_c2 == US_level) &&     /* handle case where xds rating has no vsld modifier */
630                                        ((s_p_app->settings.ratings_tv >> screen_ratings_tv_xds2pos(US_level)) & (0 | (0x1))))
631                                return 1;
632                        else
633                                if ((tmp_c2 == US_level) && (c2 & (0x38 & c2_mask))) /* VSL restriction */
634                                return 1;
635                }
636                break;
637        }
638        return 0;
639}
640
641
642/*
643 * Return 1 if rating is enabled and exceeded
644 * Return 0 if rating is disabled or not exceeded
645 * Returns -1 on invalid rating or error
646 */
647static int bapp_block(bapp_t *p_app,
648                                          unsigned char c1,                               /* xds 1 character */
649                                          unsigned char c2                                /* xds 2 character */
650                                         )
651{
652        rsys_t rsys;
653        unsigned char mask    = 0;
654        int           blocked = 0;
655
656        rsys = bapp_get_rsys(c1,c2);
657
658   BAPP_VCHIP_MSG(("%s-0x%02x,0x%02x\n",s_rsys_name[rsys],c1,c2));
659
660        switch (rsys)
661        {
662        default:
663        case eRS_MPA_OLD:
664        case eRS_MPA:
665                {
666                        unsigned char rat    = 0;
667
668                        /* determine most restrictive user selected movie rating
669                           and convert to xds equivalent. */
670                        if ((p_app->settings.ratings_movies >> 0) & (0 | (0x1)))
671                                rat = 1;
672                        else
673                                if ((p_app->settings.ratings_movies >> 1) & (0 | (0x1)))
674                                rat = 2;
675                        else
676                                if ((p_app->settings.ratings_movies >> 2) & (0 | (0x1)))
677                                rat = 3;
678                        else
679                                if ((p_app->settings.ratings_movies >> 3) & (0 | (0x1)))
680                                rat = 4;
681                        else
682                                if ((p_app->settings.ratings_movies >> 4) & (0 | (0x1)))
683                                rat = 5;
684                        else
685                                if ((p_app->settings.ratings_movies >> 5) & (0 | (0x1)))
686                                rat = 6;
687                        else
688                                if ((p_app->settings.ratings_movies >> 6) & (0 | (0x1)))
689                                rat = 7;
690                        else
691                                rat     = 0;
692
693                        BAPP_VCHIP_MSG(("@@@ settings.ratings_movie:%x rat:%d\n", p_app->settings.ratings_movies, rat));
694                        blocked = bapp_mpa_block(rat, c1);
695                        break;
696                }
697        case eRS_US:
698                {
699                        unsigned char tmp_c2 = c2 & 0x7;
700                        unsigned char d      = 0;
701                        unsigned char l      = 0;
702                        unsigned char s      = 0;
703                        unsigned char v      = 0;
704                        unsigned char fv     = 0;
705                        unsigned char rat    = 0;
706
707                        switch (tmp_c2)
708                        {
709                        case 1:
710                                mask = 0;
711                                break;
712                        case 2:
713                                /* build tv-y7 content ratings mask */
714                                fv = ((p_app->settings.ratings_tv >> ePOS_TV_Y7_FV) & (0 | (0x1)));
715                                mask = (fv << 3);
716                                break;
717                        case 3:
718                                mask = 0;
719                                break;
720                        case 4:
721                                /* build tv-pg and tv-14 content ratings mask */
722                                d = ((p_app->settings.ratings_tv >> ePOS_TV_PG_D) & (0 | (0x1)));
723                                l = ((p_app->settings.ratings_tv >> ePOS_TV_PG_L) & (0 | (0x1)));
724                                s = ((p_app->settings.ratings_tv >> ePOS_TV_PG_S) & (0 | (0x1)));
725                                v = ((p_app->settings.ratings_tv >> ePOS_TV_PG_V) & (0 | (0x1)));
726                                mask = ((v << 3) | (s << 2) | (l << 1) | (d << 0)); 
727                                break;
728                        case 5:
729                                d = ((p_app->settings.ratings_tv >> ePOS_TV_14_D) & (0 | (0x1)));
730                                l = ((p_app->settings.ratings_tv >> ePOS_TV_14_L) & (0 | (0x1)));
731                                s = ((p_app->settings.ratings_tv >> ePOS_TV_14_S) & (0 | (0x1)));
732                                v = ((p_app->settings.ratings_tv >> ePOS_TV_14_V) & (0 | (0x1)));
733                                mask = ((v << 3) | (s << 2) | (l << 1) | (d << 0)); 
734                                break;
735                        case 6:
736                                /* build tv-ma content ratings mask */
737                                d = 0;
738                                l = ((p_app->settings.ratings_tv >> ePOS_TV_MA_L) & (0 | (0x1)));
739                                s = ((p_app->settings.ratings_tv >> ePOS_TV_MA_S) & (0 | (0x1)));
740                                v = ((p_app->settings.ratings_tv >> ePOS_TV_MA_V) & (0 | (0x1)));
741                                mask = ((v << 3) | (s << 2) | (l << 1) | (d << 0)); 
742                                break;
743                        default:
744                                mask = 0;
745                                break;
746                        }
747
748                        /* determine most restrictive user selected tv rating
749                           and convert to xds equivalent. */
750                        if ((p_app->settings.ratings_tv >> ePOS_TV_Y) & (0 | (0x1)))
751                                rat = 1;
752                        else
753                                if ((p_app->settings.ratings_tv >> ePOS_TV_Y7) & (0 | (0x3)))
754                                rat = 2;
755                        else
756                                if ((p_app->settings.ratings_tv >> ePOS_TV_G) & (0 | (0x1)))
757                                rat = 3;
758                        else
759                                if ((p_app->settings.ratings_tv >> ePOS_TV_PG) & (0 | (0x1F)))
760                                rat = 4;
761                        else
762                                if ((p_app->settings.ratings_tv >> ePOS_TV_14) & (0 | (0x1F)))
763                                rat = 5;
764                        else
765                                if ((p_app->settings.ratings_tv >> ePOS_TV_MA) & (0 | (0x1F)))
766                                rat = 6;
767                        else
768                                rat     = 0;
769
770                        BAPP_VCHIP_MSG(("@@@ settings.ratings_tv:%x rat:%d\n", p_app->settings.ratings_tv, rat));
771                        blocked = bapp_US_block(rat,mask,c1,c2);
772                }
773                break;
774        case eRS_CANADIAN_ENGLISH:
775                {
776                        unsigned char rat = 0;
777
778                        /* determine most restrictive user selected tv rating
779                           and convert to xds equivalent. */
780                        if ((p_app->settings.ratings_tv >> ePOS_TV_Y) & (0 | (0x1)))
781                                rat = 1;
782                        else
783                                if ((p_app->settings.ratings_tv >> ePOS_TV_Y7) & (0 | (0x3)))
784                                rat = 2;
785                        else
786                                if ((p_app->settings.ratings_tv >> ePOS_TV_G) & (0 | (0x1)))
787                                rat = 3;
788                        else
789                                if ((p_app->settings.ratings_tv >> ePOS_TV_PG) & (0 | (0x1F)))
790                                rat = 4;
791                        else
792                                if ((p_app->settings.ratings_tv >> ePOS_TV_14) & (0 | (0x1F)))
793                                rat = 5;
794                        else
795                                if ((p_app->settings.ratings_tv >> ePOS_TV_MA) & (0 | (0x1F)))
796                                rat = 6;
797                        else
798                                rat     = 0;
799
800                        blocked = bapp_CE_block(tv_to_can_eng[rat], c2);
801                }
802                break;
803        case eRS_CANADIAN_FRENCH:
804                {
805                        unsigned char rat = 0;
806
807                        /* determine most restrictive user selected tv rating
808                           and convert to xds equivalent. */
809                        if ((p_app->settings.ratings_tv >> ePOS_TV_Y) & (0 | (0x1)))
810                                rat = 1;
811                        else
812                                if ((p_app->settings.ratings_tv >> ePOS_TV_Y7) & (0 | (0x3)))
813                                rat = 2;
814                        else
815                                if ((p_app->settings.ratings_tv >> ePOS_TV_G) & (0 | (0x1)))
816                                rat = 3;
817                        else
818                                if ((p_app->settings.ratings_tv >> ePOS_TV_PG) & (0 | (0x1F)))
819                                rat = 4;
820                        else
821                                if ((p_app->settings.ratings_tv >> ePOS_TV_14) & (0 | (0x1F)))
822                                rat = 5;
823                        else
824                                if ((p_app->settings.ratings_tv >> ePOS_TV_MA) & (0 | (0x1F)))
825                                rat = 6;
826                        else
827                                rat     = 0;
828
829                        blocked = bapp_CF_block(tv_to_can_fra[rat], c2);
830                }
831                break;
832        }
833
834        /* we go thru ratings evaluation so we can always display current
835                rating whether we are currently enforcing it or not */
836        if (p_app->settings.ratings_lock == 0)
837                blocked = 0;
838
839        BAPP_VCHIP_MSG(("%s:%d (%d %s)\n", __FUNCTION__,__LINE__,blocked,p_app->prog_rating_str));
840        {
841                static chm_event_t rating_evt;
842                rating_evt.type = eCHM_EVT_REDRAW;
843                rating_evt.id = blocked;
844                rating_evt.ticks = bos_getticks();
845                bos_post_event(p_app->msg_queue,(bapp_task_event_t*)&rating_evt);
846        }
847
848        return blocked;
849}
850
851/*
852 * Callback to process XDS data (V-CHIP)
853 */
854static void  bapp_xds_callback(int xds_class,                   /* the class (0 - current, used for vchip) */
855                                                           int xds_type,                   /* the xds type (5 - vchip) */
856                                                           unsigned char* data,    /* the data buffer, containing data_len valid bytes */
857                                                           int data_len                    /* the number of valid bytes in data */
858                                                          )
859{
860        if (data_len != 2)
861                return;
862
863        if (xds_class == 0)
864        {
865                /* Current class */
866                if (xds_type == 5)
867                {
868                        static chm_event_t chm_evt;
869                        int block = 0;
870                        struct timeval tv;
871                        unsigned int current_ticks = bos_getticks();
872
873                        /* ignore rating if ratings was received while tuned to a different channel. */
874                        if (current_ticks < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
875                                return;
876
877                        gettimeofday(&tv);
878                        s_p_app->last_xds = tv.tv_sec;
879                        /* VCHIP processing */
880                        block = bapp_block(s_p_app,data[0],data[1]);
881                        BDBG_WRN(("bapp_block(0x%02x,0x%02x) - %d, 0x%08x\n",data[0],data[1],block,current_ticks));
882
883                        if (block != -1)
884                        {
885                                s_p_app->last_rating_tick = current_ticks;
886
887                                if (block != s_p_app->last_rating_block_status)
888                                {
889                                        chm_evt.type = eCHM_EVT_BLOCK;
890                                        chm_evt.id = block;
891                                        chm_evt.ticks = current_ticks;
892                                        bos_post_event(s_p_app->msg_queue,(bapp_task_event_t*)&chm_evt);
893                                }
894                                s_p_app->last_rating_block_status = block;
895                        }
896                }
897        } else if (xds_class == 3)
898        {
899                /* Miscellaneous class */
900                if (xds_type == 1)
901                {
902                        /* time of day */
903                } else if (xds_type == 4)
904                {
905#if 0 /* JPF XDS time is unreliable in current BA broadcasts */
906
907                        /* local time zone */
908                        BDBG_WRN(("### UTC OFFSET = %d(s) ###\n", data[0] & 0x1F,(data[0] & 0x20) ? "DST" : "STD"));
909                        g_xds_time_offset = data[0] & 0x1F;
910                        g_xds_dst = (data[0] & 0x20) ? 1 : 0;
911#endif
912                }
913        }
914}
915
916/****************************************************************
917 * INPUTS:      none
918 * OUTPUTS:     none
919 * RETURNS:     number of pixels rendered
920 * DESCRITPION: Get the default palette
921 ****************************************************************/
922static void get_def_palette (unsigned int *palette)
923{
924        memcpy(palette,g_p_dsp->ui_comp.ui_palette, 16 * sizeof(unsigned int));
925}
926/****************************************************************
927 * INPUTS:      none
928 * OUTPUTS:     none
929 * RETURNS:     number of pixels rendered
930 * DESCRITPION: Get the default palette
931 ****************************************************************/
932static void get_screensaver_palette (unsigned int *palette)
933{
934#ifndef CONFIG_SCREENSAVER
935        BDBG_WRN(("No LOGO.\n"));
936#else
937//#error "No Logo"
938        bcm_raw_8_t *p_header = (bcm_raw_8_t*)g_p_dsp->ui_comp.logo;
939        uint8_t *p_clut = (uint8_t*)p_header;
940        p_clut += sizeof(bcm_raw_8_t);
941        //memcpy(palette,g_p_dsp->ui_comp.logo_palette, 16 * sizeof(unsigned int));
942        memcpy(palette,p_clut, p_header->clut_size * sizeof(unsigned int));
943#endif
944}
945/****************************************************************
946 * INPUTS:      none
947 * OUTPUTS:     none
948 * RETURNS:     number of pixels rendered
949 * DESCRITPION: Get the default palette
950 ****************************************************************/
951static void get_eia_708_palette (unsigned int *palette)
952{
953#ifdef CONFIG_EIA_708
954        memcpy(palette,g_eia708_palette, 16 * sizeof(unsigned int));
955#endif
956}
957
958/*
959Summary:
960        Set PCM audio output mode.
961Description:
962        Set PCM audio output mode, mono output when non-zero.
963*/
964void bapp_audio_out_mode(bapp_t *p_app, int mono)
965{
966        baudio_decode_config config;
967        baudio_decode_get_config(p_app->audio, &config);
968        config.mono = (mono) ? true : false;
969        baudio_decode_set_config(p_app->audio, &config);
970}
971
972/*
973Summary:
974        Set PCM audio compression mode.
975Description:
976        Set PCM audio compression  mode.
977
978Returns:
979        0 if successful
980        non zero if not
981*/
982int bapp_audio_comp_mode(bapp_t *p_app, int comp_mode)
983{
984        baudio_decode_config config;
985       
986        /* defined in com/bsettop_decode_audio.h */
987        if (comp_mode < 0 || comp_mode >= AC3_NUM_COMP_MODES)
988                return 1;
989
990        baudio_decode_get_config(p_app->audio, &config);
991        config.comp_mode = comp_mode;
992        baudio_decode_set_config(p_app->audio, &config);
993        return 0;
994}
995
996/*
997Summary:
998        Set volume level
999Description:
1000        Set Volume level (range 0 - 100)
1001*/
1002void bapp_set_audio_volume(bapp_t *p_app, uint8_t level)
1003{
1004        uint32_t new_vol = level;
1005        uint32_t cur_vol = p_app->audio_vol;
1006        uint32_t vol;
1007
1008        /* possibly cancel mute */
1009        if ((level > 0) && (p_app->audio_mute))
1010                bapp_audio_mute(p_app, 0);
1011
1012        if ((level > 100) || (new_vol == cur_vol))
1013                return;
1014
1015        if (new_vol > cur_vol)
1016        {
1017                for (p_app->audio_vol = cur_vol; p_app->audio_vol < new_vol; ++p_app->audio_vol)
1018                {
1019                        vol = (p_app->audio_vol * 0x1000)/100;
1020                        WriteReg32(BCHP_PCM_PB0_VOLUME,(vol << 16) | vol);
1021                        bos_sleep(1);
1022                }
1023        } else
1024        {
1025                for (p_app->audio_vol = cur_vol; p_app->audio_vol > new_vol; --p_app->audio_vol)
1026                {
1027                        vol = (p_app->audio_vol * 0x1000)/100;
1028                        WriteReg32(BCHP_PCM_PB0_VOLUME,(vol << 16) | vol);
1029                        bos_sleep(1);
1030                }
1031        }
1032        p_app->audio_vol = level;
1033        vol = (p_app->audio_vol * 0x1000)/100;
1034        WriteReg32(BCHP_PCM_PB0_VOLUME,(vol << 16) | vol);
1035}
1036/*
1037Summary:
1038        Mute audio
1039Description:
1040        Mute audio when enable is non-zero.
1041*/
1042void bapp_audio_mute(bapp_t *p_app, int mute)
1043{
1044        int vol,idx;
1045
1046        if ((mute && p_app->is_muted) || (!mute && !p_app->is_muted))
1047                return;
1048
1049        BDBG_WRN(("%s mute = %d, audo_vol = %d, is_muted = %d...\n",__FUNCTION__,mute,p_app->audio_vol,p_app->is_muted));
1050        if (mute)
1051        {
1052                for (idx = p_app->audio_vol; idx >= 0; --idx)
1053                {
1054                        vol = (idx * 0x1000)/100;
1055                        WriteReg32(BCHP_PCM_PB0_VOLUME,(vol << 16) | vol);
1056                        bos_sleep(1);
1057                }
1058                p_app->is_muted = true;
1059        }
1060        else
1061        {
1062                for (idx = 0; idx <= p_app->audio_vol; ++idx)
1063                {
1064                        vol = (idx * 0x1000)/100;
1065                        WriteReg32(BCHP_PCM_PB0_VOLUME,(vol << 16) | vol);
1066                        bos_sleep(1);
1067                }
1068                p_app->is_muted = false;
1069        }
1070}
1071/*
1072Summary:
1073        Mute both audio and video.
1074Description:
1075        Mute both audio and video when enable is non-zero.
1076*/
1077void bapp_av_mute(bapp_t *p_app, int mute)
1078{
1079        bdecode_config cfg;
1080        bapp_audio_mute(p_app,mute);
1081        bdecode_get_config(p_app->decode,&cfg);
1082        if (mute)
1083                cfg.mute = 1;
1084        else
1085                cfg.mute = 0;
1086       
1087        bdecode_set_config(p_app->decode,&cfg);
1088}
1089/*
1090Summary:
1091        Configure the video output mode.
1092Description:
1093        Configure the video output mode.
1094*/
1095void bapp_output_mode(bapp_t *p_app, int widescreen)
1096{
1097        bdecode_config cfg;
1098        bdecode_get_config(p_app->decode,&cfg);
1099        if (widescreen)
1100        {
1101                BDBG_WRN(("Widescreen...\n"));
1102                cfg.widescreen = 1;
1103        } else
1104        {
1105                BDBG_WRN(("Full Screen...\n"));
1106                cfg.widescreen = 0;
1107        }
1108        bdecode_set_config(p_app->decode,&cfg);
1109}
1110
1111/*
1112Summary:
1113        Apply the current settings.
1114Description:
1115        Apply the current settings. Restart decode.
1116*/
1117void bapp_apply_settings(bapp_t *p_app)
1118{
1119        p_app->cur_ch_num = p_app->settings.cur_ch_num;
1120        p_app->audio_vol  = p_app->settings.audio_vol;
1121        p_app->lang       = p_app->settings.language;
1122
1123        bapp_output_mode(p_app, (p_app->settings.picture == 0) ? 0 : 1);
1124        bapp_audio_out_mode(p_app,0);
1125        bapp_set_audio_volume(p_app, p_app->audio_vol);
1126}
1127
1128/*
1129Summary:
1130        Reset the current user settings
1131Description:
1132        Reset the current user settings.  Note this does not change them in flash.
1133*/
1134void bapp_reset_settings(bapp_t *p_app)
1135{
1136        memset(&p_app->settings, 0, sizeof(p_app->settings));
1137        {
1138                int i = 0;
1139                for (i = 0; i < MAX_RRT_DIM; i++)
1140                {
1141                        p_app->settings.ratings_rrt[i] = 0;
1142                }
1143        }
1144        p_app->settings.rrt_status = eRRT_UNAVAILABLE;
1145        p_app->settings.last_rrt_id = 0;
1146
1147        bapp_reset_cc_settings(p_app);
1148        p_app->settings.auto_power = 0;
1149        p_app->settings.audio_vol = 100;
1150        p_app->settings.dst = 1;
1151        /* this will make sure volume is reset to default from UI */
1152        p_app->audio_vol = p_app->settings.audio_vol;
1153}
1154
1155/*
1156Summary:
1157    Reset the current advanced closed captioning user settings
1158Description:
1159    Reset the current advanced closed captioning user settings.  Note this does not change them in flash.
1160*/
1161void bapp_reset_cc_settings(bapp_t *p_app)
1162{
1163        p_app->settings.captions_font         = 0;
1164        p_app->settings.captions_font_size    = 0;
1165        p_app->settings.captions_font_style   = 0;
1166        p_app->settings.captions_font_color   = 0;
1167        p_app->settings.captions_font_opacity = 0;
1168        p_app->settings.captions_back_color   = 0;
1169        p_app->settings.captions_back_opacity = 0;
1170        p_app->settings.captions_edge_color   = 0;
1171        p_app->settings.captions_edge_type    = 0;
1172}
1173
1174/*
1175Summary:
1176        Load current settings from NVM
1177Description:
1178        Load current settings from NVM
1179*/
1180void bapp_load_settings(bapp_t *p_app)
1181{
1182        bapp_settings_t *p_flash_data = NULL;
1183        uint32_t flash_data_length;
1184
1185        if (fstore_get(&p_app->flash_storage, eFS_APP_DATA, (void **)&(p_flash_data), &flash_data_length) == b_ok)
1186        {
1187                if (flash_data_length == sizeof(p_app->settings))
1188                {
1189                        /* flash data valid - use it! */
1190                        BDBG_WRN(("flash app data length CORRECT:%d (should be %d) restore settings\n", flash_data_length, sizeof(p_app->settings)));
1191
1192
1193                        memcpy(&p_app->settings,p_flash_data,sizeof(bapp_settings_t));
1194                        return;
1195                }
1196        }
1197
1198        /* flash contains invalid saved data */
1199        BDBG_WRN(("flash app data length incorrect:%d (should be %d) save defaults\n", flash_data_length, sizeof(p_app->settings)));
1200
1201        /* When the flash is empty and the settings get reset to defaults here,
1202           the current implementation of bapp_save_settings will wipe of the default
1203           values for volume, language and cur_ch_num with the current app values.
1204           To avoid this set the app values after calling bapp_reset_settings.
1205           I have fixed this several times but someone keeps removing this fix. 
1206           Do not remove this change without addressing and  understanding this issue. */
1207        bapp_reset_settings(p_app);
1208        p_app->cur_ch_num   =    p_app->settings.cur_ch_num;
1209        p_app->audio_vol    =    p_app->settings.audio_vol;
1210        p_app->lang         =    p_app->settings.language;
1211
1212        /* update flash with new settings */
1213        bapp_save_settings(p_app);
1214}
1215
1216/*
1217Summary:
1218        Save current settings to NVM
1219Description:
1220        Save current settings to NVM
1221*/
1222void bapp_save_settings(bapp_t *p_app)
1223{
1224        /* update unsaved settings */
1225        p_app->settings.cur_ch_num = p_app->cur_ch_num;
1226        p_app->settings.audio_vol  = p_app->audio_vol;
1227        p_app->settings.language   = p_app->lang;
1228
1229        bapp_stop_decode(p_app);
1230        bos_sleep(200); /* need to make sure decode is stopped before saving settings */
1231
1232        p_app->settings_dirty = false;
1233        if (fstore_update(&p_app->flash_storage, eFS_APP_DATA, &p_app->settings, sizeof(p_app->settings)) != b_ok)
1234        {
1235                BDBG_WRN(("fstore_update failed\n"));
1236        } else
1237        {
1238                BDBG_WRN(("fstore_update success\n"));
1239        }
1240}
1241/*
1242Summary:
1243        Power down audio DAC and power off
1244*/
1245void bapp_do_poweroff(bapp_t *p_app)
1246{
1247#if (BCHP_CHIP != 3543)
1248
1249                /* Notifiy MCU of desire to power off */
1250#ifndef CONFIG_OLD_MCU
1251                WriteReg32(BCHP_GIO_DATA_LO, ReadReg32( BCHP_GIO_DATA_LO) & ~(1UL << 20));
1252#else
1253                WriteReg32(BCHP_GIO_DATA_LO, ReadReg32( BCHP_GIO_DATA_LO) | (1UL << 20));
1254#endif
1255#else
1256                WriteReg32(BCHP_AIO_MISC_DAC_PWRDOWN,0x0000000F);
1257                WriteReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1, 
1258                                   ReadReg32( BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1) & ~BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1_irw_top_sw_pwroff_MASK);
1259                bos_sleep(20);
1260                WriteReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1, 
1261                                   ReadReg32( BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1) | BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1_irw_top_sw_pwroff_MASK);
1262
1263#endif
1264}
1265
1266/*
1267Summary:
1268        Initialize the main app structure.
1269Description:
1270        Do necessary configuration of main app structure.  Assumes
1271        p_app is allocated and p_surf and palette are initialized.
1272*/
1273static bgfx_io_t s_io =
1274{
1275        bin_read,
1276        bin_tell,
1277        bin_set
1278};
1279
1280void bapp_init(bapp_t *p_app)
1281{
1282
1283        bapp_lang_t e_lang;
1284        bdecode_config cfg;
1285#ifdef CONFIG_HAS_VIDEO
1286        bdecode_config cfgs[2];
1287#endif
1288#ifdef LINUX
1289        bsurface_create_settings cfg;
1290        bdisplay_settings settings;
1291        bsurface_memory mem;
1292        bsurface_t framebuffer;
1293        bgraphics_palette settop_palette;
1294#else
1295        unsigned int *palette;  /* [out] address of palette */
1296        int width;                              /* [out] width of the OSD surface  */
1297        int height;                             /* [out] height of the OSD surface  */
1298        int pitch;                              /* [out] pitch of the OSD surface  */
1299#endif
1300
1301        BDBG_MSG(("%s:%d\n",__FUNCTION__,__LINE__));
1302        memset(p_app,0,sizeof(bapp_t));
1303
1304        s_p_app = p_app;
1305
1306        /* Enable number UI navigation */
1307#if (BCHP_CHIP!=3543)
1308        p_app->button_numbers = true;
1309#else
1310        p_app->button_numbers = ((ReadReg32(BCHP_GIO_DATA_HI) & STRP_NUM_DIS_MASK) == 0) ? true : false;
1311#endif
1312
1313        WriteReg32(SCRATCH_CMD_BASE,0);/* make sure there are no values in the Command scratch register on start */
1314
1315        /* Configure GPIO for output (LEDs) */
1316        WriteReg32(LED_IODIR_REG, ReadReg32( LED_IODIR_REG) & ~(LED_IODIR_MASK));
1317
1318#if (BCHP_CHIP!=3543)
1319
1320        /* Configure the MCU Power_Off_Ready as output */
1321        WriteReg32(BCHP_GIO_IODIR_LO, ReadReg32( BCHP_GIO_IODIR_LO) & ~(1UL << 20));
1322#else
1323#if 0
1324
1325        /* Enable front pannel reset control */
1326        WriteReg32(BCHP_SUN_TOP_CTRL_RESET_CTRL,
1327                           ReadReg32( BCHP_SUN_TOP_CTRL_RESET_CTRL) |
1328                           (BCHP_SUN_TOP_CTRL_RESET_CTRL_front_panel_reset_enable_MASK |
1329                                BCHP_SUN_TOP_CTRL_RESET_CTRL_front_panel_reset_polarity_MASK));
1330#endif
1331#endif
1332
1333        BAPP_ASSERT(bsettop_init(BSETTOP_VERSION) == b_ok);
1334
1335#if (BCHP_CHIP != 3543)
1336        p_app->user_io = buser_input_open(B_ID(USERIO_ID));
1337#else
1338        {
1339                unsigned event_cnt;
1340                int ir_result;
1341                buser_input_event event;
1342
1343                unsigned int type = (ReadReg32(BCHP_GIO_DATA_HI) & STRP_REMOTE_MASK) >> STRP_REMOTE_SHIFT;
1344
1345#ifndef CONFIG_XMP_REMOTE
1346                if (type < 4)
1347                        p_app->user_io = buser_input_open(B_ID(s_remote_type_map[type]));
1348                else
1349                        p_app->user_io = buser_input_open(B_ID(4));
1350#else
1351                /*RLQ, temp solution, will use type once it is ready */
1352                type = type;
1353                BDBG_ERR(("%s: USERIO_ID=%d", __func__, USERIO_ID));
1354                p_app->user_io = buser_input_open(B_ID(USERIO_ID));
1355#endif
1356
1357#ifndef CONFIG_FAST_IR
1358#error "Use fast IR"
1359                {
1360                        int start_ticks;
1361                        /* See if there is an IR code pending */
1362                        WriteReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1,
1363                                           ReadReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1) | 
1364                                           BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1_irw_top_sw_req_ir_code_MASK);
1365       
1366                        /* Check for event */
1367                        start_ticks = bos_getticks() + MS_TO_TICKS(150);
1368                        while ((ir_result = buser_input_get_event(p_app->user_io,&event,1,&event_cnt)) != b_ok)
1369                        {
1370                                if (bos_getticks() > start_ticks)
1371                                {
1372                                        BDBG_ERR(("TIMEOUT:  Waited > 150 ms for key: (ir_result = %d, event=0x%08x (%d events))\n",ir_result,event.code,event_cnt));
1373                                        break;
1374                                }
1375                        }
1376                        if ((ir_result != b_ok) || (event_cnt < 1) || (event.code != eIR_POWER))
1377                        {
1378                                BDBG_ERR(("Wake up not caused by power button or IR key (ir_result = %d, event=0x%08x (%d events))\n",ir_result,event.code,event_cnt));
1379                                bos_sleep(100);
1380                                /* Power off */
1381                                bapp_do_poweroff(p_app);
1382                        } else
1383                        {
1384                                BDBG_ERR(("Powered on OK (ir_result = %d, event=0x%08x)\n",ir_result,event.code));
1385                        }
1386                }
1387#else
1388                ir_result = buser_input_get_event(p_app->user_io,&event,1,&event_cnt);
1389#endif
1390                p_app->check_poweron = true;
1391                p_app->poweron_ms = bos_getticks() + MS_TO_TICKS(3000);
1392
1393        }
1394
1395#endif
1396
1397        p_app->display = bdisplay_open(B_ID(0));
1398
1399        WriteReg32(SCRATCH_CMD_BASE,0);/* make sure there are no values in the Command scratch register on start */
1400
1401#if (BCHP_CHIP == 7002) || (BCHP_CHIP == 3563)
1402        btransport_open();
1403#endif
1404
1405#ifdef LINUX
1406        bdisplay_get(p_app->display, &settings);
1407        settings.format = bvideo_format_ntsc;
1408        settings.content_mode = bdisplay_content_mode_panscan;
1409        BAPP_ASSERT(bdisplay_set(p_app->display, &settings) == b_ok);
1410#endif
1411
1412        p_app->decode = bdecode_open(0);
1413        BAPP_ASSERT(p_app->decode);
1414
1415#ifdef CONFIG_HAS_VIDEO
1416
1417        /* Initialise for both record PID channels */
1418        bdecode_get_config(p_app->decode, &cfgs[0]);
1419        bdecode_get_config(p_app->decode, &cfgs[1]);
1420
1421        bmessage_init(cfgs);
1422        smessage_init(cfgs);
1423#else
1424        bmessage_init(NULL);
1425#endif 
1426
1427        p_app->window = bdecode_window_open(0, p_app->display);
1428
1429        bdecode_get_config(p_app->decode,&cfg);
1430        cfg.xds_callback = bapp_xds_callback;
1431        bdecode_set_config(p_app->decode,&cfg);
1432
1433#ifdef CONFIG_HAS_AUDIO
1434        p_app->audio = baudio_decode_open(B_ID(0));
1435        if (!p_app->audio)
1436        {
1437                BDBG_WRN(("baudio_decode_open failed\n"));
1438        }
1439        p_app->audio_mute = 0;
1440#endif
1441
1442        bstream_mpeg_init(&p_app->mpeg);
1443
1444        p_app->tuner = btuner_open((0));
1445        BAPP_ASSERT(p_app->tuner);
1446
1447        bos_create_queue(&p_app->msg_queue, p_app->msg_event, MAX_MSG_EVENT);
1448        BAPP_ASSERT(p_app->msg_queue);
1449
1450        p_app->smsg = smessage_open(bmessage_format_psi);
1451        p_app->msg = bmessage_open(bmessage_format_ts);
1452
1453        BAPP_ASSERT(p_app->msg);
1454
1455        p_app->graphics = bgraphics_open(B_ID(0),p_app->display);
1456
1457        p_app->yield_ms = APP_DEFAULT_YIELD;
1458        p_app->lang = eLANG_ENGLISH;
1459
1460#ifdef LINUX
1461        p_app->width = 720;
1462        p_app->height = 480;
1463        bsurface_create_settings_init(&cfg, p_app->graphics);
1464        cfg.pixel_format = bgraphics_pixel_format_palette4;
1465
1466        framebuffer = bgraphics_create_framebuffer(p_app->graphics, &cfg, false);
1467
1468        bsurface_get_memory(framebuffer, &mem);
1469
1470        get_def_palette(&(p_app->palette));
1471        settop_palette.length = 16;
1472        settop_palette.palette = p_app->palette.clut;
1473
1474        bsurface_load_clut(framebuffer, settop_palette);
1475        p_app->osd_mem = (unsigned char *)mem.buffer;
1476        p_app->osd_mem_size = mem.pitch * p_app->height;
1477#else
1478        bgraphics_get_framebuffer(p_app->graphics,(void**)&p_app->osd_mem,(unsigned int **)&palette,&width,&height,&pitch);
1479        get_def_palette(palette);
1480        bgraphics_load_palette(p_app->graphics);
1481        p_app->osd_mem_size = pitch * height;
1482        p_app->width = width;
1483        p_app->height = height;
1484        BDBG_MSG(("%s:%d - Width = %d, Height = %d, Pitch = %d.\n",__FUNCTION__,__LINE__,width,height,pitch));
1485#endif
1486
1487        BDBG_MSG(("%s:%d - Initialize screens.\n",__FUNCTION__,__LINE__));
1488
1489        /* Default to NULL (empty) screen (TODO:  goto factory test then setup wizard.) */
1490        p_app->screen_id = eSCREEN_BANNER_SMALL;
1491
1492        p_app->p_screens = g_screens;
1493        p_app->num_screens = g_screens_num;
1494
1495        BDBG_MSG(("%s:%d - Initialize bgfx.\n",__FUNCTION__,__LINE__));
1496        /* initialize bgfx */
1497        bgfx_init(&s_io,NULL);
1498
1499        /* Create the OSD surface to use for all drawing */
1500        BAPP_ASSERT(bgfx_create(&p_app->surf,p_app->width,p_app->height,(uint8_t*)p_app->osd_mem,
1501                                                        pitch,&p_app->palette, BGFX_SURF_PRIMARY) == 0);
1502
1503        bgfx_fill_rect(&p_app->surf,0,0,p_app->width,p_app->height,0x0);
1504
1505        BDBG_MSG(("%s:%d - Load fonts.\n",__FUNCTION__,__LINE__));
1506
1507        memset(&s_font[eFONT_SIZE_SMALL],0,sizeof(bgfx_font_t) * 3);
1508        p_app->br.cnt = 0;
1509        p_app->br.data = g_p_dsp->ui_comp.small_font;
1510        p_app->br.size = g_p_dsp->ui_comp.small_font_size;
1511
1512        BAPP_ASSERT(bgfx_load_font(&(s_font[eFONT_SIZE_SMALL]),&p_app->br) == 0);
1513
1514        p_app->br.cnt = 0;
1515        p_app->br.data = g_p_dsp->ui_comp.medium_font;
1516        p_app->br.size = g_p_dsp->ui_comp.medium_font_size;
1517
1518        BAPP_ASSERT(bgfx_load_font(&(s_font[eFONT_SIZE_MED]),&p_app->br) == 0);
1519
1520        p_app->br.cnt = 0;
1521        p_app->br.data = g_p_dsp->ui_comp.large_font;
1522        p_app->br.size = g_p_dsp->ui_comp.large_font_size;
1523
1524        BAPP_ASSERT(bgfx_load_font(&(s_font[eFONT_SIZE_LARGE]),&p_app->br) == 0);
1525        for (e_lang = eLANG_ENGLISH; e_lang < eLANG_MAX; ++e_lang)
1526        {
1527                p_app->p_font[e_lang][eFONT_SIZE_SMALL] = &s_font[eFONT_SIZE_SMALL];
1528                p_app->p_font[e_lang][eFONT_SIZE_MED] = &s_font[eFONT_SIZE_MED];
1529                p_app->p_font[e_lang][eFONT_SIZE_LARGE] = &s_font[eFONT_SIZE_LARGE];
1530        }
1531
1532        p_app->ratings_override         = false;
1533        /* reset so ratings will be re-evaluated when returned to full tv */
1534        p_app->last_rating_block_status      = -1;
1535        /* assume psip unblock */
1536        p_app->last_psip_rating_block_status = 0;
1537#ifdef CONFIG_RFM
1538        {
1539                bdisplay_settings display_settings;
1540        boutput_rf_settings rf_settings;
1541
1542        bdisplay_get(p_app->display, &display_settings);
1543        display_settings.rf = boutput_rf_open(B_ID(0));
1544        boutput_rf_get(display_settings.rf, &rf_settings);
1545        rf_settings.channel = eRFM_CH3;
1546        if (ReadReg32(RFM_CH4_REG) & RFM_CH4_MASK)
1547            rf_settings.channel = eRFM_CH4;
1548        boutput_rf_set(display_settings.rf, &rf_settings);
1549        bdisplay_set(p_app->display, &display_settings);
1550        boutput_rf_set_audio_volume(display_settings.rf, DEFAULT_RFM_VOLUME);
1551        }
1552#endif
1553#if 0
1554        {
1555                uint32_t    value;
1556                value = (BCHP_HIFIDAC_CTRL0_DAC_VOLUME_DAC_VOL_MASK * (uint32_t)DEFAULT_VOLUME) / 100;
1557                WriteReg32(BCHP_HIFIDAC_CTRL0_DAC_VOLUME,
1558                                   (ReadReg32(BCHP_HIFIDAC_CTRL0_DAC_VOLUME) & ~BCHP_HIFIDAC_CTRL0_DAC_VOLUME_DAC_VOL_MASK) |
1559                                   (value << BCHP_HIFIDAC_CTRL0_DAC_VOLUME_DAC_VOL_SHIFT));
1560        }
1561#else
1562        WriteReg32(BCHP_HIFIDAC_CTRL0_DAC_VOLUME,0x904C);
1563#endif
1564
1565#ifdef CONFIG_EIA_708
1566        p_app->eia708 = bapp_eia708_open(p_app);
1567        BAPP_ASSERT(p_app->eia708);
1568        bdecode_get_config(p_app->decode,&cfg);
1569    cfg.cc_callback = bapp_eia708_cb;
1570        bdecode_set_config(p_app->decode,&cfg);
1571#endif /* CONFIG_EIA_708 */
1572
1573        chm_init(&p_app->chm,p_app);
1574
1575#if (DEF_CH_MAP > 0)
1576        memcpy(p_app->settings.ch,s_def_ch_map, g_def_ch_num * sizeof(s_def_ch_map[0]));
1577        p_app->settings.num_channels = g_def_ch_num;
1578#endif /* DEF_CH_MAP */
1579
1580        BAPP_ASSERT(fstore_init(&(p_app->flash_storage)) == b_ok);
1581
1582#if (BCHP_CHIP==3543)
1583        /* Check GPIO 33 and 34, if pressed then go into factory test mode */
1584        if ((ReadReg32(BUTTON_DATA_REG) & CH_DOWN_BUTTON_MASK) == CH_DOWN_BUTTON_MASK)
1585        {
1586                p_app->screen_id = eSCREEN_STATUS;
1587                p_app->factory_test = true;
1588
1589        } else
1590#endif
1591        {
1592                bapp_load_settings(p_app);
1593                bapp_apply_settings(p_app);
1594        }
1595}
1596/*
1597Summary:
1598        Main app event handler.
1599Description:
1600        Main application event handler.
1601*/
1602void bapp_handle_event(bapp_t *p_app, bscreen_event_t *p_event)
1603{
1604        int idx;
1605
1606        if (p_event && (p_event->type == eS_EVENT_IR) && (p_event->id >= eIR_CHMAP))
1607        {
1608                switch (p_event->id)
1609                {
1610                case eIR_CHMAP: /* Output channel map on UART */
1611                        for (idx = 0; idx < p_app->settings.num_channels; ++idx)
1612                        {
1613#ifdef DTA_TEST
1614extern const unsigned short s_ch_to_freq[];
1615                                printf("{%d,%d,%d,%d,%d,%d,%d,%d,{%d,%d,%d},{0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x}, 0x%02x},\n",
1616                                           p_app->settings.ch[idx].major,
1617                                           p_app->settings.ch[idx].minor,
1618                                           p_app->settings.ch[idx].program_number,
1619                                           p_app->settings.ch[idx].freq_idx,
1620                                           s_ch_to_freq[p_app->settings.ch[idx].freq_idx],
1621                                           p_app->settings.ch[idx].psi,
1622                                           p_app->settings.ch[idx].pcr_pid,
1623                                           p_app->settings.ch[idx].video_pid,
1624                                           p_app->settings.ch[idx].audio_pid[0],
1625                                           p_app->settings.ch[idx].audio_pid[1],
1626                                           p_app->settings.ch[idx].audio_pid[2],
1627                                           p_app->settings.ch[idx].ch_name[0],p_app->settings.ch[idx].ch_name[1],p_app->settings.ch[idx].ch_name[2],
1628                                           p_app->settings.ch[idx].ch_name[3],p_app->settings.ch[idx].ch_name[4],p_app->settings.ch[idx].ch_name[5],
1629                                           p_app->settings.ch[idx].ch_name[6],p_app->settings.ch[idx].program_number );
1630#else
1631                                printf("{%d,%d,%d,%d,%d,%d,{%d,%d,%d},{0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x, 0x%04x}, 0x%02x},\n",
1632                                           p_app->settings.ch[idx].major,
1633                                           p_app->settings.ch[idx].minor,
1634                                           p_app->settings.ch[idx].freq_idx,
1635                                           p_app->settings.ch[idx].psi,
1636                                           p_app->settings.ch[idx].pcr_pid,
1637                                           p_app->settings.ch[idx].video_pid,
1638                                           p_app->settings.ch[idx].audio_pid[0],
1639                                           p_app->settings.ch[idx].audio_pid[1],
1640                                           p_app->settings.ch[idx].audio_pid[2],
1641                                           p_app->settings.ch[idx].ch_name[0],p_app->settings.ch[idx].ch_name[1],p_app->settings.ch[idx].ch_name[2],
1642                                           p_app->settings.ch[idx].ch_name[3],p_app->settings.ch[idx].ch_name[4],p_app->settings.ch[idx].ch_name[5],
1643                                           p_app->settings.ch[idx].ch_name[6],p_app->settings.ch[idx].cmd );
1644#endif                 
1645                        }
1646                        break;
1647
1648                case eIR_SCAN: /* Perform channel scan */
1649                        bapp_channel_scan(p_app);
1650                        break;
1651                case eIR_SETUP: /* Perform default setup */
1652                        p_app->settings.wiz_completed = 1;
1653                        bapp_channel_scan(p_app);
1654                        break;
1655                case eIR_EXIT: /* Exit to banner menu */
1656                        bapp_set_current_screen(p_app, eSCREEN_BANNER_SMALL, eSCREEN_NULL);
1657                        break;
1658                default:
1659                        if ((p_event->id & eIR_SETCH) == eIR_SETCH)
1660                        {
1661                                p_app->cur_ch_num = (p_event->id & ~eIR_SETCH); /* Set channel index (7 lsb are channel index) */
1662                                if (p_app->cur_ch_num >= p_app->settings.num_channels)
1663                                        p_app->cur_ch_num = 0;
1664                                bapp_set_current_screen(p_app, eSCREEN_BANNER_SMALL, eSCREEN_NULL);
1665                        }
1666                        break;
1667                }
1668        }
1669}
1670
1671/*
1672Summary:
1673        Main app idle time handler.
1674Description:
1675        Main application idle time handler.
1676*/
1677#define BAPP_CAD_TIMEOUT        10 /* in seconds */
1678void bapp_idle(bapp_t *p_app)
1679{
1680        struct timeval tv;
1681        static chm_event_t chm_evt;
1682        bool   rating_timeout = false;
1683        uint32_t current_ticks = bos_getticks();
1684
1685        if (p_app->check_poweron)
1686        {
1687                if (p_app->poweron_ms < bos_getticks())
1688                {
1689                        p_app->check_poweron = false;
1690                }
1691        }
1692
1693        /* Do global idle time processing here like. */
1694        gettimeofday(&tv);
1695
1696        /* check if last psip rating has timed out */
1697        if ((p_app->last_cad + BAPP_CAD_TIMEOUT) < tv.tv_sec)
1698        {
1699                if (p_app->last_psip_rating_block_status == 1)
1700                {
1701                        BDBG_WRN(("clear PSIP rating to unrated - timed out! %d\n",tv.tv_sec));
1702                        p_app->last_psip_rating_block_status = 0;
1703                        /* clear ratings string */
1704                        rating_timeout = true;
1705                }
1706                p_app->psip_rating_str[0] = 0;
1707        }
1708
1709        /* check if last xds rating has timed out */
1710        if ((p_app->last_rating_tick + MS_TO_TICKS(BAPP_VCHIP_TIMEOUT)) < current_ticks)
1711        {
1712                if (p_app->last_rating_block_status == 1)
1713                {
1714                        BDBG_WRN(("clear XDS rating to unrated - timed out! (0x%08x)\n",current_ticks));
1715                        p_app->last_rating_block_status = 0;
1716                        /* clear ratings string */
1717                        rating_timeout = true;
1718                }
1719                p_app->prog_rating_str[0] = 0;
1720        }
1721
1722        /* send unblock message if both rating types have timed out */
1723        if ((rating_timeout) &&
1724                (p_app->last_rating_block_status != 1) && (p_app->last_psip_rating_block_status != 1))
1725        {
1726                BDBG_WRN(("current rating timed out - unblocking!"));
1727                /* Unblock since a previous rating has timed out */
1728                chm_evt.type = eCHM_EVT_BLOCK;
1729                chm_evt.id = 0;
1730                chm_evt.ticks = current_ticks;
1731                bos_post_event(s_p_app->msg_queue,(bapp_task_event_t*)&chm_evt);
1732        }
1733}
1734/*
1735Summary:
1736        Wait for vsync.
1737Description:
1738        Block waiting for vsync so drawing can by syncronized with screen refresh.
1739*/
1740void bapp_sync(bapp_t *p_app)
1741{
1742        /* do nothing */
1743}
1744
1745/*
1746Summary:
1747        Enable closed captioning.
1748Description:
1749        Enable closed captioning and send clear characters.
1750*/
1751void bapp_enable_cc(bapp_t *p_app, int enable)
1752{
1753        bdecode_config cfg;
1754        BDBG_MSG(("%s enable = %d, p_app->settings.captions_basic = %d, p_app->settings.captions_basic = %d\n",
1755                          __FUNCTION__,enable,p_app->settings.captions_basic,p_app->captions_basic));
1756#ifdef CONFIG_EIA_708
1757               
1758                bapp_eia708_enable(p_app->eia708,((enable == 0) ? false : ((p_app->settings.captions_basic > 0) ? true : false)));
1759#endif
1760        bdecode_get_config(p_app->decode,&cfg);
1761        if (cfg.cc_enabled != enable)
1762        {
1763                cfg.cc_enabled = (enable == 0) ? 0 : 1;
1764                bdecode_set_config(p_app->decode,&cfg);
1765        }
1766}
1767
1768/*
1769Summary:
1770        Handle new screen.
1771Description:
1772        Block waiting for vsync so drawing can by syncronized with screen refresh.
1773*/
1774void bapp_new_screen(bapp_t *p_app)
1775{
1776        static int screen_id = -1;
1777        bscreen_event_t screen_event;
1778#ifdef TIME_APP_DRAWING
1779        struct timeval start_tv,end_tv,result_tv;
1780        unsigned int dt;
1781#endif
1782        screen_event.type = 0;
1783        if (screen_id != (int)p_app->screen_id)
1784        {
1785                BDBG_MSG(("%s:%d - sending setup event to %d.\n",__FUNCTION__,__LINE__,p_app->screen_id));
1786                screen_event.type = eS_EVENT_SETUP;
1787                screen_event.id = 0;
1788                p_app->p_screens[p_app->screen_id].handle_event(p_app,(void*)&(p_app->p_screens[p_app->screen_id]),&screen_event);
1789        }
1790
1791        screen_id = p_app->screen_id;
1792#ifdef TIME_APP_DRAWING
1793        GETTIMEOFDAY(&start_tv);
1794#endif
1795       
1796        //BDBG_MSG(("%s:%d - drawing screen:%d.\n",__FUNCTION__,__LINE__,p_app->screen_id));
1797        if (!bapp_eia708_enabled(p_app->eia708))
1798        {
1799                bapp_sync(p_app);
1800                p_app->p_screens[p_app->screen_id].draw(p_app,(void*)&(p_app->p_screens[p_app->screen_id]));
1801                bapp_flush_screen(p_app);
1802        }
1803#ifdef TIME_APP_DRAWING
1804        GETTIMEOFDAY(&end_tv);
1805        timeval_subtract(&result_tv,&end_tv,&start_tv);
1806        dt = result_tv.tv_sec * 1000 + result_tv.tv_usec/1000;
1807        BDBG_WRN(("Drawing screen %d took %d ms\n",p_app->screen_id,dt));
1808#endif
1809
1810        /* send a setup done event to start any post drawing setup */
1811        if (screen_event.type == eS_EVENT_SETUP)
1812        {
1813                screen_event.type = eS_EVENT_SETUP_DONE;
1814                screen_event.id = 0;
1815                if (p_app->p_screens[p_app->screen_id].handle_event(p_app,(void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
1816                {
1817                        screen_id = p_app->screen_id;
1818                        screen_event.type = eS_EVENT_SETUP;
1819                        screen_event.id = 0;
1820                        p_app->p_screens[p_app->screen_id].handle_event(p_app,(void*)&(p_app->p_screens[p_app->screen_id]),&screen_event);
1821#ifdef TIME_APP_DRAWING
1822                        GETTIMEOFDAY(&start_tv);
1823#endif
1824                        if (!bapp_eia708_enabled(p_app->eia708))
1825                        {
1826                                bapp_sync(p_app);
1827                                p_app->p_screens[p_app->screen_id].draw(p_app,(void*)&(p_app->p_screens[p_app->screen_id]));
1828                                bapp_flush_screen(p_app);
1829                        }
1830#ifdef TIME_APP_DRAWING
1831                        GETTIMEOFDAY(&end_tv);
1832                        timeval_subtract(&result_tv,&end_tv,&start_tv);
1833                        dt = result_tv.tv_sec * 1000 + result_tv.tv_usec/1000;
1834                        BDBG_WRN(("Drawing took %d milliseconds\n",dt));
1835#endif
1836                }
1837        }
1838}
1839
1840/*
1841Summary:
1842        Clear screen selection history
1843Description:
1844        Clear screen selection history
1845*/
1846void bapp_clear_screen_selection_history(bapp_t *p_app)
1847{
1848        int i;
1849
1850        for (i = 0; i < p_app->num_screens; i++)
1851        {
1852                p_app->p_screens[i].button_selection = 0;
1853        }
1854}
1855
1856/*
1857Summary:
1858        sets the current screen for display
1859Description:
1860        sets the current screen for display. 
1861        if id == eSCREEN_MAX then simply backup a screen
1862        if save_last == eSCREEN_MAX, also saves last screen id.
1863        else save_last is used for the last screen id (use eSCREEN_NULL if you want the last screen id to refer to live tv)
1864*/
1865void bapp_set_current_screen(bapp_t *p_app, bapp_screen_id_t id, bapp_screen_id_t save_last)
1866{
1867        bscreen_t *p_screen     = &(p_app->p_screens[p_app->screen_id]);
1868        bscreen_t *p_screen_new = &(p_app->p_screens[id]);
1869#ifdef BCM_DEBUG
1870        unsigned int cur_screen = p_app->screen_id;
1871#endif
1872        BDBG_WRN(("Attempt to change screen from %d to %d\n",cur_screen, id));
1873
1874        if (id == p_app->screen_id)
1875                return;
1876
1877        if (id == eSCREEN_MAX)
1878        {
1879                bapp_goto_last_screen(p_app);
1880        } else
1881        {
1882                if (save_last == eSCREEN_MAX)
1883                        p_screen_new->last_screen_id = p_app->screen_id;
1884                else
1885                {
1886                        p_screen_new->last_screen_id = save_last;
1887                        p_screen->button_selection = 0; /* if we do not save the last screen, clear out focus history */
1888                }
1889
1890                if (id < eSCREEN_MAX)
1891                        p_app->screen_id = id;
1892        }
1893
1894        if (p_app->screen_id == eSCREEN_NULL)
1895        {
1896                p_app->screen_id = eSCREEN_BANNER_SMALL; /* Default to channel change screen */
1897        }
1898        BDBG_WRN(("Changing screen from %d to %d\n",cur_screen, p_app->screen_id));
1899
1900        if (p_app->screen_id != eSCREEN_BANNER_SMALL)
1901        {
1902                bapp_av_mute(p_app, 1);
1903                bapp_enable_cc(p_app, 0);
1904        } else
1905        {
1906                /* recheck ratings block status which may have changed while in menu */
1907                bapp_handle_blocking(p_app);
1908
1909        }
1910}
1911
1912/*
1913Summary:
1914        sets the current screen for display to be the last screen
1915Description:
1916        sets the current screen for display to be the last screen
1917*/
1918void bapp_goto_last_screen(bapp_t *p_app)
1919{
1920        bscreen_t *p_screen     = &(p_app->p_screens[p_app->screen_id]);
1921        p_app->screen_id = p_screen->last_screen_id;
1922        if (p_app->screen_id == eSCREEN_NULL)
1923        {
1924                p_app->screen_id = eSCREEN_BANNER_SMALL; /* Default to channel change screen */
1925        }
1926
1927        if (p_app->screen_id != eSCREEN_BANNER_SMALL)
1928        {
1929                bapp_av_mute(p_app, 1);
1930                bapp_enable_cc(p_app, 0);
1931        }
1932}
1933/*
1934Summary:
1935        Handle content advisory blocking/unblocking.
1936        Returns 1 if blocking/unblocking results in a screen change, 0 otherwise
1937*/
1938int bapp_handle_blocking(bapp_t *p_app)
1939{
1940        int             screen_changed = 0;
1941
1942        if (p_app->ratings_override)
1943                return screen_changed;
1944
1945        BDBG_MSG(("last_psip_rating_block_status:%d last_rating_block_status:%d\n", p_app->last_psip_rating_block_status ,p_app->last_rating_block_status));
1946
1947        /* check both types of ratings - if either one says "block", we block */
1948        if ((p_app->last_psip_rating_block_status == 1) || (p_app->last_rating_block_status == 1))
1949        {
1950                /* show pin verification screen if not in menus */
1951                if ((p_app->screen_id == eSCREEN_BANNER_SMALL) ||
1952                        (p_app->screen_id == eSCREEN_NULL))
1953                {
1954                        bapp_set_current_screen(p_app, eSCREEN_PIN_VERIFY_LIVE, eSCREEN_NULL);
1955                        screen_changed = 1;
1956                }
1957        } else
1958        {
1959                /* no blocking, need to re-enable decode and possibly hide pin verification screen */
1960                if ((p_app->screen_id == eSCREEN_PIN_VERIFY_LIVE) ||
1961                        (p_app->screen_id == eSCREEN_WRONG_PIN_LIVE))
1962                {
1963                        bapp_set_current_screen(p_app, eSCREEN_NULL, eSCREEN_NULL);
1964                        screen_changed = 1;
1965                }
1966        }
1967        return screen_changed;
1968}
1969
1970
1971/*
1972Summary:
1973        Turn power on or off
1974Description:
1975        Turn power on if power = true, turn power off otherwise
1976*/
1977void bapp_power(bapp_t *p_app, bool power)
1978{
1979        unsigned int flags;
1980       
1981        if (p_app->factory_test || (p_app->power == power))
1982        {
1983                if (p_app->factory_test)
1984                {
1985                        bapp_set_current_screen(p_app, eSCREEN_STATUS, eSCREEN_NULL);
1986                        bapp_new_screen(p_app);
1987                }
1988                return;
1989        }
1990
1991        if (!power && p_app->check_poweron)
1992        {
1993                return;
1994        }
1995
1996        bapp_stop_decode(p_app);
1997
1998        if (power)
1999        {
2000                /* turning power on */
2001                BDBG_ERR(("######## Turn ON ########\n"));
2002
2003                /* turning power leds on */
2004                flags = bos_enter_critical();
2005#if (BCHP_CHIP!=3543)
2006                WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) & ~LED_RED_MASK);
2007#else
2008                WriteReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1, 
2009                                   ReadReg32( BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1) & ~BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1_irw_top_sw_led_cntrl_MASK);
2010#endif
2011                WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) | LED_GREEN_MASK);
2012                bos_exit_critical(flags);
2013
2014                bapp_set_palette(p_app, ePALETTE_DEFAULT);
2015
2016                /* restore settings */
2017                p_app->cur_ch_num = p_app->settings.cur_ch_num;/* restore last tuned channel */
2018                p_app->audio_vol  = p_app->settings.audio_vol; /* restore last volume level */
2019                p_app->audio_mute = false; /* ensure audio mute user setting is off */
2020                if (p_app->settings.wiz_completed)
2021                {
2022                        bapp_set_current_screen(p_app, eSCREEN_BANNER_SMALL, eSCREEN_NULL);
2023                }
2024        else
2025                {
2026            bapp_set_current_screen(p_app, eSCREEN_WIZ_LANGUAGE, eSCREEN_WIZ_LANGUAGE);
2027                }
2028
2029                bapp_new_screen(p_app);
2030
2031#if (BCHP_CHIP!=3543)
2032#ifndef CONFIG_OLD_MCU
2033                WriteReg32(BCHP_GIO_DATA_LO, ReadReg32( BCHP_GIO_DATA_LO) | (1UL << 20));
2034#endif
2035#endif
2036
2037                /* UNCOMMENT lines below to test new RRT user notification */
2038                /*
2039                BDBG_WRN(("######################### reset rrt region/version \n"));
2040                p_app->settings.last_rrt_id  = 0;
2041                p_app->settings.rrt_status   = eRRT_UNAVAILABLE;
2042                p_app->settings.ratings_lock = 1;
2043                */
2044        } else
2045        {
2046                /* Put tuner in bypass mode. Only valid for DTT76809, but shouldn't affect
2047                   other tuners either */
2048                // Only for VSB p_app->ds.rfBypass = true;
2049                btuner_tune_ds(p_app->tuner, 0, &p_app->ds);
2050
2051                /* turning power off */
2052                uint32_t current_tick = bos_getticks();
2053                BDBG_ERR(("######## Turn OFF @ 0x%08x ########\n",TICKS_TO_MS(current_tick)));
2054
2055                /* check for auto power off */
2056                if ((p_app->screen_id != eSCREEN_POWER_OFF) &&
2057                        (p_app->settings.auto_power != 3)            &&
2058                        (current_tick >= (p_app->last_keypress_tick + MS_TO_TICKS(AUTO_POWER_OFF_TIMEOUT) * (1 + p_app->settings.auto_power))))
2059                {
2060                        p_app->settings.auto_power_off = 1;
2061                }
2062
2063                flags = bos_enter_critical();
2064                /* turning power leds off */
2065#if (BCHP_CHIP!=3543)
2066                WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) | LED_RED_MASK);
2067#else
2068                WriteReg32(BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1, 
2069                                   ReadReg32( BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1) | BCHP_SUN_TOP_CTRL_GENERAL_CTRL_1_irw_top_sw_led_cntrl_MASK);
2070#endif
2071                WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) & ~LED_GREEN_MASK);
2072                bos_exit_critical(flags);
2073
2074                bapp_av_mute(p_app, 1);
2075                bapp_set_current_screen(p_app, eSCREEN_POWER_OFF, eSCREEN_NULL);
2076                bapp_new_screen(p_app);
2077
2078                /* save settings if saved channel number or saved volume level is incorrect
2079                   note that these settings are saved here because the change often during
2080                   normal stb operation and there is no need to maintain this information
2081                   except between power cycles.  these settings are also duplicated in both
2082                   the settings struct and the p_app struct.*/
2083                if ((p_app->settings.cur_ch_num != p_app->cur_ch_num) || 
2084                        (p_app->settings.audio_vol != p_app->audio_vol) || 
2085                        (p_app->settings.language != p_app->lang) ||
2086                        p_app->settings.auto_power_off || p_app->settings_dirty)
2087        {
2088                        p_app->settings.cur_ch_num = p_app->cur_ch_num;
2089                        p_app->settings.audio_vol  = p_app->audio_vol;
2090                        p_app->settings.language   = p_app->lang;
2091                        bapp_save_settings(p_app);
2092                }
2093                printf("######## NOTIFY POWERCTRL ########\n");
2094
2095                /* Wait to avoid power button repeat keys from remote */
2096                bos_sleep(2000);
2097
2098                bapp_do_poweroff(p_app);
2099        }
2100
2101        p_app->power = power;
2102}
2103
2104/*
2105Summary:
2106        Main app loop.
2107Description:
2108        Main application event loop.
2109*/
2110void bapp_run(bapp_t *p_app)
2111{
2112        buser_input_event event;
2113        unsigned event_cnt;
2114        bscreen_event_t screen_event;
2115        chm_event_t *p_event;
2116
2117        p_app->done = 0;
2118        BDBG_MSG(("%s:%d - Start running.\n",__FUNCTION__,__LINE__));
2119
2120        bapp_power(p_app, true);
2121
2122        while (!p_app->done)
2123        {
2124                /* Check for UI event */
2125                if (buser_input_get_event(p_app->user_io,&event,1,&event_cnt) == b_ok)
2126                {
2127#ifdef BCM_DEBUG
2128                        static bool s_test_flag = false;
2129                        if (!s_test_flag)
2130#endif
2131                        {
2132                                if (event_cnt > 0)
2133                                {
2134                                        p_app->last_keypress_tick = bos_getticks();
2135                                }
2136                        }
2137
2138                        if (event_cnt && ((int)event.code == eIR_POWER))
2139                        {
2140                                /* power key handled here since it is always available regardless
2141                                   of the currently shown screen.  note: power key is consumed
2142                                   here and not passed on to any screens.
2143                                 */
2144                                bapp_power(p_app, !p_app->power);
2145                        } else if (event_cnt && ((event.code & eIR_RFM) == eIR_RFM))
2146                        {
2147                                bdisplay_settings settings;
2148                                boutput_rf_settings rf_settings;
2149                                if (event.code & 0x40000000)
2150                                        continue;
2151                                bdisplay_get(p_app->display,&settings);
2152                                boutput_rf_get(settings.rf, &rf_settings);
2153                                rf_settings.channel = eRFM_CH3;
2154                                bos_sleep(50);
2155                                rf_settings.channel = (event.code == 0x71) ? eRFM_CH3 : eRFM_CH4;       /* CH3/CH4 */
2156                                BDBG_ERR(("%s:%d set RFM CH%d (code = 0x%08x)\n",__FUNCTION__,__LINE__,(rf_settings.channel == eRFM_CH3) ? 3 : 4,event.code));
2157                                boutput_rf_set(settings.rf, &rf_settings);
2158                                bapp_audio_mute(p_app,1);
2159                                bdisplay_set(p_app->display, &settings);
2160                                boutput_rf_set_audio_volume(settings.rf, DEFAULT_RFM_VOLUME);
2161                                bapp_audio_mute(p_app,0);
2162                                continue;
2163                        } else if (event_cnt && ((int)event.code >= 0))
2164                        {
2165                                BDBG_WRN(("%s:%d event_cnt = %d event 0x%08x(%s)\n",__FUNCTION__,__LINE__,
2166                                                  event_cnt,event.code,(event.code & 0x40000000) ? "up" : "down"));
2167
2168                                screen_event.type = eS_EVENT_IR;
2169                                screen_event.id = event.code;
2170#ifdef BCM_DEBUG
2171                                if (screen_event.id == 0x3A)
2172                                {
2173                                        BDBG_WRN(("Enter status screen from screen %d\n",p_app->screen_id));
2174                                        bapp_set_current_screen(p_app, eSCREEN_STATUS, eSCREEN_NULL);
2175                                        bapp_new_screen(p_app);
2176                                } else if (screen_event.id == 0x3B)
2177                                {
2178                                        BDBG_WRN(("Enter debug screen from screen %d\n",p_app->screen_id));
2179                                        bapp_set_current_screen(p_app, eSCREEN_DEBUG, eSCREEN_NULL);
2180                                        bapp_new_screen(p_app);
2181                                } else if (screen_event.id == 0xd7)
2182                                {
2183#if 0
2184                                        p_app->ui_debug_mode = !p_app->ui_debug_mode;
2185                                        BDBG_WRN(("UI Debug Mode %d\n",p_app->ui_debug_mode));
2186                                        bapp_flush_screen(p_app);
2187                                        p_app->p_screens[p_app->screen_id].draw(p_app,(void*)&(p_app->p_screens[p_app->screen_id]));
2188#else
2189                                        {
2190                                                uint32_t current_tick = bos_getticks();
2191
2192                                                p_app->last_keypress_tick = current_tick - (MS_TO_TICKS(AUTO_POWER_OFF_TIMEOUT) * (1 + p_app->settings.auto_power) - MS_TO_TICKS(1000 * 60));
2193                                                BDBG_WRN(("Simulation auto power off last = %d, current = %d\n",p_app->last_keypress_tick,current_tick));
2194                                                s_test_flag = true;
2195                                        }
2196                                        continue;
2197#endif
2198                                } else
2199#endif /* BCM_DEBUG */
2200                                        if (p_app->p_screens[p_app->screen_id].handle_event(p_app,
2201                                                                                                                                                (void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
2202                                {
2203                                        BDBG_MSG(("%s:%d screen_id %d\n",__FUNCTION__,__LINE__,p_app->screen_id));
2204                                        /* Wait for vsync then do screen drawing */
2205                                        bapp_new_screen(p_app);
2206                                } else
2207                                {
2208                                        bapp_handle_event(p_app,&screen_event);
2209                                }
2210                        }
2211                }
2212
2213                if (!p_app->factory_test)
2214                {
2215                        unsigned int flags = bos_enter_critical();
2216                        WriteReg32(LED_DATA_REG, ReadReg32( LED_DATA_REG) | LED_GREEN_MASK);
2217                        bos_exit_critical(flags);
2218                }
2219
2220                /* Check for notification events */
2221                if ((p_event = (chm_event_t*)bos_pend_event(p_app->msg_queue,0)) != NULL)
2222                {
2223                        screen_event.type = eS_EVENT_MAX;
2224                        screen_event.id = p_event->id;
2225                        switch (p_event->type)
2226                        {
2227                        case eCHM_EVT_SIGNAL:
2228                                {
2229                                        chm_signal_event_t *p_sig = (chm_signal_event_t*)p_event;
2230                                        p_app->lock = (p_sig->lock) ? true : false;
2231                                        p_app->signal_level = p_sig->power;
2232                                        p_app->tuned_freq = p_sig->freq_hz;
2233                                        p_app->snr = p_sig->SNR;
2234                                        p_app->qam_b_mode = p_sig->qam_b_mode;
2235                                }
2236                                break;
2237                        case eCHM_EVT_CANCEL: screen_event.type = eS_EVENT_CANCEL; break;
2238                        case eCHM_EVT_DONE: screen_event.type = eS_EVENT_DONE; break;
2239                        case eCHM_EVT_REDRAW: screen_event.type = eS_EVENT_REDRAW; break;
2240                        case eCHM_PROGRESS: screen_event.type = eS_EVENT_PROGRESS; break;
2241                        case eCHM_EVT_CAD:
2242                                {
2243                                        unsigned char blocked;
2244                                        unsigned char region,dim,val;
2245                                        struct timeval tv;
2246                                        uint32_t current_ticks = bos_getticks();
2247
2248                                        /* ignore rating if ratings was received while tuned to a different channel. */
2249                                        if (current_ticks < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
2250                                                break;
2251
2252                                        gettimeofday(&tv);
2253                                        BDBG_WRN(("PSIP Ratings @ %d\n",tv.tv_sec));
2254                                        s_p_app->last_cad = tv.tv_sec;
2255                                        blocked = (uint8_t)(screen_event.id >> 24) & 0xFF;
2256                                        region  = (uint8_t)(screen_event.id >> 16) & 0xFF;
2257                                        dim = (uint8_t)(screen_event.id >> 8) & 0xFF;
2258                                        val = (uint8_t)(screen_event.id & 0xFF);
2259
2260                                        if ((s_p_app->ratings_region != region) || (s_p_app->ratings_dim != dim) || (s_p_app->ratings_val != val))
2261                                        {
2262                                                s_p_app->ratings_region = region;
2263                                                s_p_app->ratings_dim = dim;
2264                                                s_p_app->ratings_val = val;
2265                                        }
2266
2267                                        p_app->last_psip_rating_block_status = blocked; 
2268                                        if (bapp_handle_blocking(p_app))
2269                                                screen_event.type = eS_EVENT_SETUP;
2270                                        else /* Update OSD */
2271                                                screen_event.type = eS_EVENT_REDRAW;
2272                                }
2273                                break;
2274                        case eCHM_EVT_BLOCK:
2275                                /* ignore rating if ratings was received while tuned to a different channel. */
2276                                if (bos_getticks() < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
2277                                        break;
2278
2279                                /* p_app->last_rating_block_status = screen_event.id; - not necessary because already updated by bapp_xds_callback() */
2280                                if (bapp_handle_blocking(p_app))
2281                                        screen_event.type = eS_EVENT_SETUP;
2282                                break;
2283                        case eCHM_EVT_RRT:
2284                                {
2285                                        unsigned char rating_region;
2286                                        unsigned char version_number;
2287                                        uint32_t current_ticks = bos_getticks();
2288
2289                                        if (p_app->settings.ratings_lock < 2)
2290                                                break;
2291
2292                                        /* ignore rating if ratings was received while tuned to a different channel. */
2293                                        if (current_ticks < (s_p_app->last_tune_tick + MS_TO_TICKS(BAPP_RATINGS_EVAL_DELAY)))
2294                                                break;
2295
2296                                        rating_region     = (uint8_t)(screen_event.id >> 8) & 0xFF;
2297                                        version_number    = (uint8_t)(screen_event.id & 0x1F);
2298                                        if (rating_region == 1)
2299                                                break;
2300
2301                                        /* this will be dealt with in the default screen idle loop since we only want
2302                                           to alter rrt settings when the user is not in the menu system. */
2303                                        if (screen_event.id != p_app->settings.last_rrt_id)
2304                                        {
2305                                                BDBG_WRN(("####### NEW RRT(0x%02x,0x%02x) ###\n",rating_region,version_number));
2306                                                p_app->settings.last_rrt_id = screen_event.id;
2307                                                p_app->settings.rrt_status = eRRT_AVAILABLE;
2308                                                switch (p_app->screen_id)
2309                                                {
2310                                                case eSCREEN_RATINGS:
2311                                                case eSCREEN_RATINGS_LOCK:
2312                                                case eSCREEN_RATINGS_LIMITS:
2313                                                case eSCREEN_RATINGS_TV:
2314                                                case eSCREEN_RATINGS_MOVIES:
2315                                                case eSCREEN_RATINGS_RRT_DIM:
2316                                                case eSCREEN_RATINGS_RRT_VAL:
2317                                                case eSCREEN_RATINGS_RRT_UPDATE:
2318                                                        bapp_set_current_screen(p_app, eSCREEN_RATINGS_RRT_UPDATE, eSCREEN_NULL);
2319                                                        bapp_new_screen(p_app);
2320                                                        break;
2321                                                default:
2322                                                        bapp_set_current_screen(p_app, eSCREEN_RATINGS_RRT_UPDATE, eSCREEN_MAX);
2323                                                        bapp_new_screen(p_app);
2324                                                        break;
2325                                                }
2326                                        }
2327                                }
2328                                break;
2329                        case eCHM_EVT_CSD: /* Do nothing */
2330                                break;
2331                        }
2332                        BDBG_MSG(("%s:%d CHM EVENT = %d)\n",__FUNCTION__,__LINE__,p_event->type));
2333
2334                        if (p_app->p_screens[p_app->screen_id].handle_event(p_app,
2335                                                                                                                                (void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
2336                        {
2337                                BDBG_MSG(("%s:%d screen_id %d\n",__FUNCTION__,__LINE__,p_app->screen_id));
2338                                /* Wait for vsync then do screen drawing */
2339                                bapp_new_screen(p_app);
2340                        } else
2341                        {
2342                                bapp_handle_event(p_app,&screen_event);
2343                        }
2344                }
2345
2346                /* Yield control */
2347                bapp_sleep(p_app->yield_ms);
2348
2349
2350                screen_event.type = eS_EVENT_IDLE;
2351                screen_event.id = 0;
2352                /* Give screen idle time to handle menu timeouts, etc */
2353                if (p_app->p_screens[p_app->screen_id].handle_event(p_app,
2354                                                                                                                        (void*)&(p_app->p_screens[p_app->screen_id]),&screen_event))
2355                {
2356                        /* Wait for vsync then do screen drawing */
2357                        bapp_new_screen(p_app);
2358                }
2359
2360                /* Do application idle time processing */
2361                bapp_idle(p_app);
2362        }
2363
2364        /* finish */
2365        bmessage_uninit();
2366        bsettop_uninit();
2367}
2368
2369/*
2370Summary:
2371        Check current channel for SAP
2372Description:
2373        Check current channel for SAP, and set current_sap to -1 if no, otherwise current lang as base to rotate
2374*/
2375void bapp_check_sap(bapp_t *p_app)
2376{
2377
2378        p_app->num_sap = 0;
2379        if (p_app->settings.ch[p_app->cur_ch_num].audio_pid[0])
2380                p_app->num_sap++;
2381        if (p_app->settings.ch[p_app->cur_ch_num].audio_pid[1])
2382                p_app->num_sap++;
2383        if (p_app->settings.ch[p_app->cur_ch_num].audio_pid[2])
2384                p_app->num_sap++;
2385
2386        BDBG_WRN(("%s p_app->num_sap = %d\n",__FUNCTION__,p_app->num_sap));
2387}
2388
2389/*
2390Summary:
2391   Tune to the current frequency and get the VCT.
2392Description:
2393        Tune to the current frequency and get the VCT. Returns non-zero on failure.
2394*/
2395int bapp_change_channel(bapp_t *p_app, int ch_up, int tune)
2396{
2397        int retval = -1;
2398
2399        if (p_app->settings.num_channels)
2400        {
2401                int i = 0;
2402                p_app->last_ch_num = p_app->cur_ch_num;
2403
2404                /* search for the next "active" channel in ch list */
2405                for (i = 0; (i < p_app->settings.num_channels); i++)
2406                {
2407                        if (ch_up)
2408                        {
2409                                p_app->cur_ch_num++;
2410                                if (p_app->cur_ch_num >=  p_app->settings.num_channels)
2411                                        p_app->cur_ch_num = 0;
2412                        } else
2413                        {
2414                                if (p_app->cur_ch_num == 0)
2415                                {
2416                                        p_app->cur_ch_num = p_app->settings.num_channels - 1;
2417                                } else
2418                                        p_app->cur_ch_num--;
2419                        }
2420
2421                        if (!p_app->settings.ch[p_app->cur_ch_num].hidden)
2422                                break;
2423                }
2424
2425                BDBG_ERR(("bapp_change_channel %d.%d\n",p_app->settings.ch[p_app->cur_ch_num].major,p_app->settings.ch[p_app->cur_ch_num].minor));
2426                if (tune)
2427                {
2428                        retval = bapp_tune(p_app);
2429                } else
2430                {
2431                        retval = 0;
2432                }
2433    }
2434        return retval;
2435}
2436
2437/*
2438Summary:
2439   Tune to the specified channel.
2440Description:
2441        Tune to the specified channel or nearest to the channel. Returns non-zero on failure.
2442*/
2443int bapp_set_channel(bapp_t *p_app, int major, int minor)
2444{
2445        int retval = -1; 
2446        int i      = 0;
2447
2448        BDBG_ERR(("bapp_set_channel %d.%d\n",major,minor));
2449
2450        /* search channel list for channel data */
2451        for (i = 0; i < p_app->settings.num_channels; i++)
2452        {
2453                if (major == 0)
2454                        continue;
2455
2456                if ((p_app->settings.ch[i].major == major) &&
2457                        (p_app->settings.ch[i].minor == minor))
2458                {
2459                        /* found matching channel */
2460                        if (p_app->cur_ch_num != i)
2461                        {
2462                                p_app->last_ch_num = p_app->cur_ch_num;
2463                                p_app->cur_ch_num = i;
2464                                retval = bapp_tune(p_app);
2465                        } else
2466                        {
2467                                /* already tuned to correct channel so do nothing */
2468                                retval = 0;
2469                        }
2470                }
2471        }
2472
2473        return retval;
2474}
2475/*
2476Summary:
2477   Perform a channel scan.
2478Description:
2479        Perform a channel scan. Returns non-zero on failure.
2480*/
2481int bapp_channel_scan(bapp_t *p_app)
2482{
2483        p_app->settings.cur_ch_num = 0;
2484        p_app->cur_ch_num = 0;
2485        chm_cmd(&p_app->chm,eCHM_SCAN);
2486        return 0;
2487}
2488
2489/*
2490Summary:
2491   Tune to the current channel.
2492*/
2493int bapp_tune(bapp_t *p_app)
2494{
2495        /* only tune necessary */
2496        if ((p_app->cur_ch_num == p_app->chm.cur_ch_num) && 
2497                (p_app->chm.cur_ch_num != 0xFF) &&
2498                (p_app->decoding))
2499                return 0;
2500
2501        p_app->current_sap = p_app->lang;
2502        p_app->captions_basic = p_app->settings.captions_basic;
2503
2504        if (p_app->ratings_override_set)
2505        {
2506                p_app->ratings_override_set = false;
2507        }
2508        else
2509        {
2510        p_app->ratings_override         = false;
2511        }
2512       
2513        /* reset so ratings will be re-evaluated when returned to full tv */
2514        p_app->last_rating_block_status = -1;
2515        /* assume psip unblock */
2516        p_app->last_psip_rating_block_status = 0;
2517        /* clear ratings string */
2518        p_app->prog_rating_str[0] = 0;
2519        p_app->psip_rating_str[0] = 0;
2520        BDBG_WRN(("Reset rating string @ %d\n",__LINE__));
2521
2522        chm_cmd(&p_app->chm,eCHM_TUNE);
2523        p_app->decoding         = true;
2524        p_app->last_tune_tick   = bos_getticks();
2525
2526        return 0;
2527}
2528/*
2529Summary:
2530   Stop decoding audio and video
2531*/
2532int bapp_stop_decode(bapp_t *p_app)
2533{
2534        chm_cmd(&p_app->chm,eCHM_STOP);
2535        p_app->decoding = false;
2536        return 0;
2537}
2538/*
2539Summary:
2540   Restart decoding audio and video
2541*/
2542int bapp_restart_decode(bapp_t *p_app)
2543{
2544        bapp_stop_decode(p_app);
2545        bapp_tune(p_app);
2546        return 0;
2547}
2548
2549/*
2550Summary:
2551   Restart audio decode (after SAP swap audio PID)
2552*/
2553int bapp_rotate_audio_sap(bapp_t *p_app)
2554{
2555        bapp_check_sap(p_app);
2556        if (p_app->num_sap <= 1)
2557        {
2558                BDBG_WRN(("p_app->num_sap = %d\n",p_app->num_sap));
2559                return -1;
2560        }
2561
2562        p_app->current_sap++;
2563        p_app->current_sap  %= 3;       /* max 3 SAP */
2564        if (0 == p_app->settings.ch[p_app->cur_ch_num].audio_pid[p_app->current_sap])
2565                p_app->current_sap = (p_app->current_sap + 1) % 3;      /* in case only two SAPs */
2566
2567        BDBG_WRN(("audio[%d].pid=%d\n", p_app->current_sap, p_app->settings.ch[p_app->cur_ch_num].audio_pid[p_app->current_sap]));
2568        baudio_decode_stop(p_app->audio);
2569        // Need to update for new stream structures   p_app->stream->mpeg.audio[0].pid = p_app->settings.ch[p_app->cur_ch_num].audio_pid[p_app->current_sap];
2570        baudio_decode_start(p_app->audio, (void *)1, p_app->stream);
2571        return 0;
2572}
2573
2574/*
2575Summary:
2576   set CLUT
2577*/
2578void bapp_set_palette(bapp_t *p_app, bapp_palette_t palette)
2579{
2580        unsigned int *clut;      /* [out] address of palette */
2581        int width;                              /* [out] width of the OSD surface  */
2582        int height;                             /* [out] height of the OSD surface  */
2583        int pitch;                              /* [out] pitch of the OSD surface  */
2584
2585        bgraphics_get_framebuffer(p_app->graphics,(void**)&p_app->osd_mem,(unsigned int **)&clut,&width,&height,&pitch);
2586
2587        switch (palette)
2588        {
2589        case ePALETTE_SCREENSAVER:
2590                get_screensaver_palette(clut);
2591                break;
2592        case ePALETTE_EIA_708:
2593                get_eia_708_palette(clut);
2594                break;
2595        case ePALETTE_DEFAULT:
2596        default:
2597                get_def_palette(clut);
2598                break;
2599        }
2600
2601        bgraphics_load_palette(p_app->graphics);
2602}
2603
2604/*
2605Summary:
2606        returns true is sufficient signal strength, false otherwise
2607        always returns true for TUNE_DURATION msecs after tuning begins.
2608*/
2609bool bapp_get_signal_status(bapp_t *p_app)
2610{
2611        static bool     first_call           = true;
2612        static bool     good_signal          = true;
2613        static uint32_t last_video_pts       = 0;
2614        static uint32_t last_video_pts_ticks = 0;
2615        static uint32_t last_audio_pts       = 0;
2616        static uint32_t last_audio_pts_ticks = 0;
2617
2618        bdecode_status    status;
2619        uint32_t          current_ticks = bos_getticks();
2620
2621        /* check for tune duration timeout - this is used to restrict display of the 'no signal'
2622           popup for a period of time (TUNE_DURATION) after tuning */
2623        if (current_ticks < (p_app->last_tune_tick + MS_TO_TICKS(TUNE_DURATION)))
2624                return true;
2625
2626        /* if no channels, don't bother doing any more checking */
2627        if (p_app->settings.num_channels == 0)
2628                return false;
2629
2630        /* if the stream is audio only return true */
2631        if ((p_app->settings.ch[p_app->cur_ch_num].video_pid == 0) && (p_app->settings.ch[p_app->cur_ch_num].audio_pid != 0))
2632                return true;
2633
2634        /* if first time calling function get baseline video pts
2635         * then wait 500msecs and continue.  since we require 2 samples
2636         * of decoder status at least 500msecs apart to determine signal
2637         * status, we need to "prime the pump" on the very first call only
2638         */
2639        if (first_call)
2640        {
2641                first_call = false;
2642                status.audio_decode = p_app->audio;
2643                bdecode_get_status(p_app->decode,&status);
2644                last_video_pts       = status.video_pts;
2645                last_video_pts_ticks = current_ticks;
2646                bos_sleep(500);
2647                current_ticks = bos_getticks();
2648
2649        last_audio_pts      = status.audio_pts;
2650        }
2651
2652        /* make sure video pts is changing - indicates successful decoding.
2653         * only check every 500msecs or so
2654         */
2655        if ((current_ticks - last_video_pts_ticks) > MS_TO_TICKS(500))
2656        {
2657                status.audio_decode = p_app->audio;
2658                bdecode_get_status(p_app->decode,&status);
2659
2660                /* if pts is changing, we are decoding properly */
2661                good_signal = (last_video_pts != status.video_pts);
2662
2663        if (good_signal == false)
2664        {
2665            good_signal = (last_audio_pts != status.audio_pts);
2666        }
2667        last_audio_pts = status.audio_pts;
2668                BDBG_MSG(("good_signal:%d vpts:0x%08x last_vpts:0x%08x ticks:%d", good_signal, status.video_pts, last_video_pts, current_ticks));
2669
2670                last_video_pts = status.video_pts;
2671                last_video_pts_ticks = current_ticks;
2672        }
2673
2674        return good_signal;
2675}
2676
2677/*
2678Summary:
2679        Set closed captions options
2680Description:
2681        Set closed captions options
2682*/
2683void bapp_set_captions_options(bapp_t *p_app)
2684{
2685        BDBG_ERR(("%s current %d, new %d", __FUNCTION__,p_app->settings.captions_basic,p_app->captions_basic));
2686        if (p_app->captions_basic != p_app->settings.captions_basic)
2687        {
2688                p_app->settings.captions_basic = p_app->captions_basic;
2689                p_app->settings_dirty = true;
2690        }
2691}
2692/*
2693Summary:
2694        Main entry point
2695*/
2696#ifdef LINUX
2697
2698int main(void)
2699{
2700        static bapp_t app;
2701
2702        bapp_init(&app);
2703        bapp_run(&app);
2704}
2705#endif
2706
2707
Note: See TracBrowser for help on using the repository browser.