source: svn/trunk/newcon3bcm2_21bu/dta/src/settop_api/bsettop_display.c

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 74.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#include "bsettop_display.h"
22#include "gist.h"
23#include "bstd.h"
24#include "bsettop_display_priv.h"
25#include "bchp_int_id_video_enc_intr2.h"
26#include "bchp_misc.h"  /* custimize BandGap Adjust */
27#include "bsettop_hdmi.h"
28#include "bvbi_priv.h"
29
30BDBG_MODULE(bsettop_display);
31
32static BERR_Code bdisplay_set_sd_output_options(bdisplay_t display, bsettop_display_id_t id, bdisplay_sd_output_options options);
33static BERR_Code bdisplay_set_hdmi_output_options(bdisplay_t display);
34static BFMT_VideoFmt bdisplay_hdmi_format_auto();
35static BFMT_VideoFmt bdisplay_hdmi_format_to_bfmt(bsettop_display_format_t fmt);
36static BERR_Code bdisplay_set_graphics_sharpness(bdisplay_t display, bsettop_display_id_t id, unsigned char index);
37static bresult bdisplay_p_vbi_connect(bdisplay_t display);
38static bresult bdisplay_p_vbi_open(bdisplay_t display);
39static bresult bdisplay_p_vbi_disconnect(bdisplay_t display);
40static bresult bdisplay_p_vbi_close(bdisplay_t display);
41
42struct bdisplay b_displays[B_N_DISPLAYS] = 
43{
44        {
45                false,                  /* Not opened */
46                {
47                        bdisplay_format_auto,
48                        NULL,           /* normaly used to notify HDMI of rate change */
49                        NULL,           /* passed to rate_change_cb */
50                        NULL,           /* RF output */
51                        NULL,           /* SPDIF output */
52                        NULL,           /* I2S output */
53                        bdisplay_sd_output_options_auto,
54                        bdisplay_hd_output_options_auto,
55                },
56                { 0, 0 }, /* displayInfo */
57                NULL,
58                NULL,
59                {
60#if HAS_HDMI
61                        { NULL, NULL, NULL, NULL, NULL, NULL},
62#endif
63                        { NULL, NULL, NULL, NULL, NULL, NULL},
64                },
65                BFMT_VideoFmt_e480p,
66                BFMT_AspectRatio_e4_3,
67                BFMT_AspectRatio_e4_3,
68                NULL,
69                NULL,
70                NULL,
71        NULL,
72#ifdef CONFIG_GFX_ARGB32
73                BPXL_eA8_R8_G8_B8,
74#else
75                BPXL_eP4,
76#endif
77                eBSURFACE_0
78        },
79};
80
81
82
83#ifdef CONFIG_SPDIF
84struct boutput_spdif
85{
86        bool update;
87        boutput_spdif_settings cfg;
88};
89
90static struct boutput_spdif b_spdif_output = 
91{
92        true,                                           /* Update S/PDIF settings */
93        {
94                true,                                   /* Enable S/PDIF Output */
95                false,                                  /* Disable Copy Protection Toggling */
96                false,                                  /* Disable channel status and validity bit handling */
97                eAUDIO_OUT_CH_CFG_NORM, /* Lin->Lout, Rin->Rout */
98                1,                                              /* V bit polarity */
99                0x00,                                   /* Low channel status bits for left channel [0:31] */
100                0x00,                                   /* Low channel status bits for right channel [0:31] */
101                0x00,                                   /* High channel status bits for both channels [41:32] */
102                true,                                   /* Always send PCM audio to SPDIF output */
103                baudio_format_unknown,  /* Compressed output format */
104        },
105};
106#endif
107
108#ifdef CONFIG_I2S
109struct boutput_i2s
110{
111        bool update;
112        boutput_i2s_settings cfg;
113};
114
115static struct boutput_i2s b_i2s_output =
116{
117        true,                                           /* Update I2S settings */
118        {
119                true,                                   /* Enable I2S Output */
120                eAUDIO_OUT_CH_CFG_NORM, /* Select what channels are output */
121                16,                                             /* 16 bits per sample */
122                true,                                   /* Set to true for MSB */
123                true,                                   /* Set to true to delay data by one SCLK period */
124                0,                                              /* Set to 0 for right samples high, left samples low clock */
125        },
126};
127#endif
128
129/**
130Summary:
131  Possible hdmi video auto output formats, from low to high
132**/
133
134static bsettop_display_format_t s_hdmi_video_auto_format[] =
135{
136        bdisplay_format_480i,
137        bdisplay_format_480p,
138        bdisplay_format_720p,
139        bdisplay_format_1080i,
140};
141#define HDMI_VIDEO_AUTO_FORMAT_NUM  (sizeof(s_hdmi_video_auto_format) / sizeof(BFMT_VideoFmt))
142
143#define VDC_MUTEX_TIMEOUT       500
144
145int b_lock_vdc(void)
146{
147    return bos_acquire_mutex(&b_displays[0].vdc_mutex, VDC_MUTEX_TIMEOUT);
148}
149
150void b_unlock_vdc(void)
151{
152    bos_release_mutex(&b_displays[0].vdc_mutex);
153}
154
155/**
156Summary:
157  Display rate change callback
158**/
159static void bdisplay_rate_change_cb(void                            *pvParam1,
160                                                                        int                              iParam2,
161                                                                        void                            *pvVdcData)
162{
163        bdisplay_t display = (bdisplay_t)pvParam1;
164        BVDC_Display_CallbackData *vdcCallbackData = (BVDC_Display_CallbackData*)pvVdcData;
165
166        display->displayInfo = vdcCallbackData->sDisplayInfo;
167        if (display->settings.rate_change_cb)
168        {
169                display->settings.rate_change_cb(display,display->settings.rate_change_data,&(display->displayInfo));
170        }
171}
172
173/**
174Summary:
175  Decoder picture ready callback
176**/
177static void MpegDataReady_isr
178( void                            *pvSourceHandle,
179  int                              iParm2,
180  void                            *pvMvdField )
181{
182        BAVC_XVD_Picture *pMvdField = (BAVC_XVD_Picture *)pvMvdField;
183
184        BVDC_Source_MpegDataReady_isr(pvSourceHandle, iParm2, (void*)pMvdField);
185        return;
186}
187/**
188Summary:
189Allocate and reserve resources for a windows.  Expects allocated bapp_nexus_t structure.
190**/
191BERR_Code bdisplay_graphics_window_close(bdisplay_t display,  bsettop_display_id_t id)
192{
193        BERR_Code rc;
194#ifdef CONFIG_NO_SD_OUTPUT
195        if (id == eBDISPLAY_COMPOSITE)
196                return BERR_SUCCESS;
197#endif
198
199        b_lock_vdc();
200        if (display->disp[id].hGfxWindow)
201        {
202                rc = BVDC_Window_Destroy(display->disp[id].hGfxWindow);
203                if (rc != BERR_SUCCESS)
204                {
205                        BDBG_ERR(("BVDC_Window_Destroy failed %d\n", rc));
206                }
207                display->disp[id].hGfxWindow = NULL;
208        }
209
210        rc = BVDC_ApplyChanges(display->hVdc);
211        if (rc != BERR_SUCCESS)
212        {
213                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
214        }
215        b_unlock_vdc();
216        return BERR_SUCCESS;
217}
218
219/**
220Summary:
221Allocate and reserve resources for a windows.  Expects allocated bapp_nexus_t structure.
222**/
223BERR_Code bdisplay_graphics_window_open(bdisplay_t display,  bsettop_display_id_t id)
224{
225        BERR_Code rc;
226        BFMT_VideoInfo formatInfo;
227        BDBG_ASSERT(display);
228        BDBG_ASSERT(display->disp[id].hGfxSource);
229#ifdef CONFIG_NO_SD_OUTPUT
230        if (id == eBDISPLAY_COMPOSITE)
231                return BERR_SUCCESS;
232#endif
233        b_lock_vdc();
234#if HAS_HDMI
235        if (id == eBDISPLAY_HDMI)
236        {
237                rc = BFMT_GetVideoFormatInfo(display->hdmiFmt,&formatInfo);
238                if (rc != BERR_SUCCESS)
239                {
240                        BDBG_ERR(("BFMT_GetVideoFormatInfo failed %d\n", rc));
241                }
242        }
243        else
244#endif
245        {
246                rc = BFMT_GetVideoFormatInfo(BFMT_VideoFmt_eNTSC,&formatInfo);
247                if (rc != BERR_SUCCESS)
248                {
249                        BDBG_ERR(("BFMT_GetVideoFormatInfo failed %d\n", rc));
250                }
251        }
252
253        rc = BVDC_Window_Create(display->disp[id].hCmp,&(display->disp[id].hGfxWindow),BVDC_WindowId_eGfx0,display->disp[id].hGfxSource,NULL);
254        if (rc != BERR_SUCCESS)
255        {
256                BDBG_ERR(("BVDC_Window_Create failed %d\n", rc));
257                goto error;
258        }
259
260        BVDC_Window_SetAlpha(display->disp[id].hGfxWindow, 0xff);
261#if 1
262        BVDC_Window_SetBlendFactor (display->disp[id].hGfxWindow, BVDC_BlendFactor_eSrcAlpha,
263                                                                BVDC_BlendFactor_eOneMinusSrcAlpha, BVDC_ALPHA_MAX);
264#else
265        BVDC_Window_SetBlendFactor (display->disp[id].hGfxWindow, BVDC_BlendFactor_eConstantAlpha,
266                                                                BVDC_BlendFactor_eOneMinusConstantAlpha, BVDC_ALPHA_MAX);
267#endif
268        BVDC_Window_SetZOrder(display->disp[id].hGfxWindow, 2);
269        BVDC_Window_SetVisibility(display->disp[id].hGfxWindow, true);
270        BVDC_Window_SetScalerOutput(display->disp[id].hGfxWindow, 0, 0, formatInfo.ulDigitalWidth, formatInfo.ulDigitalHeight);
271        BVDC_Window_SetDstRect(display->disp[id].hGfxWindow, 0, 0, formatInfo.ulDigitalWidth, formatInfo.ulDigitalHeight);
272        //BVDC_Window_SetSrcClip(display->disp[id].hGfxWindow, 0, 0, 600, 320);
273
274#if HAS_HDMI
275        if (id == eBDISPLAY_HDMI) {
276                if ((display->pxl_format == BPXL_eP4) &&
277                        ((formatInfo.eVideoFmt == BFMT_VideoFmt_eNTSC) || (formatInfo.eVideoFmt == BFMT_VideoFmt_e480p))) {
278                        BVDC_CoefficientIndex coeff;
279                        if (display->settings.sharpness < 25) { 
280                                coeff.ulSclVertLuma = display->settings.sharpness+101;
281                                coeff.ulSclHorzLuma = display->settings.sharpness+101;
282
283                                BVDC_Source_SetHorizontalScaleCoeffs(display->disp[id].hGfxSource, BVDC_FilterCoeffs_eSharp);
284                                BVDC_Window_SetCoefficientIndex(display->disp[id].hGfxWindow, &coeff);
285                        }
286                }
287                else 
288                {
289                        BVDC_Source_SetHorizontalScaleCoeffs(display->disp[id].hGfxSource, BVDC_FilterCoeffs_eAnisotropic);
290                }
291        }
292#endif
293       
294        rc = BVDC_ApplyChanges(display->hVdc);
295        if (rc != BERR_SUCCESS)
296        {
297                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
298        }
299        b_unlock_vdc();
300        return BERR_SUCCESS;
301error:
302        b_unlock_vdc();
303        bdisplay_graphics_window_close(display,id);
304        return rc;
305}
306
307#ifdef HAS_HDMI
308static BERR_Code bdisplay_set_graphics_sharpness(bdisplay_t display, bsettop_display_id_t id, unsigned char index)
309{
310        BERR_Code rc;
311        BVDC_CoefficientIndex coeff;
312
313        if ((display->pxl_format != BPXL_eP4) || (index > 25)) {
314                BDBG_ERR(("Invalid Coefficient index %d", index));
315                return BERR_SUCCESS;
316        }
317
318        coeff.ulSclVertLuma = index+101;
319        coeff.ulSclHorzLuma = index+101;
320        BVDC_Source_SetHorizontalScaleCoeffs(display->disp[eBDISPLAY_HDMI].hGfxSource, BVDC_FilterCoeffs_eSharp);
321        BVDC_Window_SetCoefficientIndex(display->disp[eBDISPLAY_HDMI].hGfxWindow, &coeff);
322        rc = BVDC_ApplyChanges(display->hVdc);
323        if (rc != BERR_SUCCESS) {
324                BDBG_ERR(("BVDC_ApplyChanges failed %d", rc));
325        }
326        return BERR_SUCCESS;
327}
328#endif
329
330/**
331Summary:
332    Allocate and reserve resources for a windows. Expects
333    allocated bapp_nexus_t structure.
334**/
335static BERR_Code bdisplay_video_window_close(bdisplay_t display,  bsettop_display_id_t id)
336{
337        BERR_Code rc;
338        BDBG_ASSERT(display);
339#ifdef CONFIG_NO_SD_OUTPUT
340        if (id == eBDISPLAY_COMPOSITE)
341                return BERR_SUCCESS;
342#endif
343        if (display->disp[id].hVideoWindow)
344        {
345                BVDC_Window_Destroy(display->disp[id].hVideoWindow);
346                display->disp[id].hVideoWindow = NULL;
347        }
348
349        rc = BVDC_ApplyChanges(display->hVdc);
350        if (rc != BERR_SUCCESS)
351        {
352                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
353        }
354        return BERR_SUCCESS;
355}
356
357/**
358Summary:
359    Allocate and reserve resources for a windows. Expects
360    allocated bapp_nexus_t structure.
361**/
362static BERR_Code bdisplay_video_window_open(bdisplay_t display,  bsettop_display_id_t id)
363{
364        BERR_Code rc;
365        BFMT_VideoInfo formatInfo;
366        BVDC_Deinterlace_Settings madSettings;
367        BVDC_Window_Settings winSettings;
368        bool deinterlace;
369#ifdef CONFIG_NO_SD_OUTPUT
370        if (id == eBDISPLAY_COMPOSITE)
371                return BERR_SUCCESS;
372#endif
373#if HAS_HDMI
374        if (id == eBDISPLAY_HDMI)
375        {
376                rc = BFMT_GetVideoFormatInfo(display->hdmiFmt,&formatInfo);
377                if (rc != BERR_SUCCESS)
378                {
379                        BDBG_ERR(("BFMT_GetVideoFormatInfo failed %d\n", rc));
380                }
381        }
382        else
383#endif
384        {
385                rc = BFMT_GetVideoFormatInfo(BFMT_VideoFmt_eNTSC,&formatInfo);
386                if (rc != BERR_SUCCESS)
387                {
388                        BDBG_ERR(("BFMT_GetVideoFormatInfo failed %d\n", rc));
389                }
390        }
391
392        BVDC_Window_GetDefaultSettings(BVDC_WindowId_eVideo0, &winSettings);
393#if (BCHP_CHIP==7552)
394        winSettings.bAllocFullScreen = true;
395        winSettings.bDeinterlacerAllocFull = true;
396        winSettings.pMinSrcFmt = BFMT_GetVideoFormatInfoPtr(BFMT_VideoFmt_e1080i);
397#if HAS_HDMI
398        if (id == eBDISPLAY_HDMI ) {
399                winSettings.pMinDspFmt = BFMT_GetVideoFormatInfoPtr(BFMT_VideoFmt_e1080i);
400        }
401#endif
402#endif
403        rc = BVDC_Window_Create(display->disp[id].hCmp,&(display->disp[id].hVideoWindow),BVDC_WindowId_eVideo0,display->hVideoSource,&winSettings);
404        if (rc != BERR_SUCCESS)
405        {
406                BDBG_ERR(("BVDC_Window_Create failed %d\n", rc));
407                goto error;
408        }
409
410        BVDC_Window_SetAlpha(display->disp[id].hVideoWindow, 0xff);
411        BVDC_Window_SetMasterFrameRate(display->disp[id].hVideoWindow,true);
412#if 0
413#if 1
414        BVDC_Window_SetBlendFactor (display->disp[id].hVideoWindow, BVDC_BlendFactor_eSrcAlpha,
415                                                                BVDC_BlendFactor_eOneMinusConstantAlpha, BVDC_ALPHA_MAX);
416#else
417        BVDC_Window_SetBlendFactor (display->disp[id].hVideoWindow, BVDC_BlendFactor_eConstantAlpha,
418                                                                BVDC_BlendFactor_eOneMinusConstantAlpha, BVDC_ALPHA_MAX);
419#endif
420#endif
421        BVDC_Window_SetForceCapture(display->disp[id].hVideoWindow, false);
422        BVDC_Window_SetZOrder(display->disp[id].hVideoWindow, 0);
423        BVDC_Window_SetVisibility(display->disp[id].hVideoWindow, true);
424
425        BVDC_Window_SetScalerOutput(display->disp[id].hVideoWindow, 0, 0, formatInfo.ulDigitalWidth, formatInfo.ulDigitalHeight);
426
427        BVDC_Window_SetDstRect(display->disp[id].hVideoWindow, 0, 0, formatInfo.ulDigitalWidth, formatInfo.ulDigitalHeight);
428
429        BVDC_Window_GetDeinterlaceConfiguration(display->disp[id].hVideoWindow,&deinterlace,&madSettings);
430#if (BCHP_CHIP==7552)
431        madSettings.stVideoTestFeature1.bEnable = true;
432        madSettings.stVideoTestFeature1.ulBitsPerPixel = 18;
433#endif
434#if HAS_HDMI
435        if (id == eBDISPLAY_HDMI)
436        {
437#ifdef SHRINK_WIDTH
438                rc = BVDC_Window_SetDeinterlaceConfiguration(display->disp[id].hVideoWindow, false, &madSettings);
439                if (rc != BERR_SUCCESS) {
440                        BDBG_WRN(("!!!!!! BVDC_Window_SetDeinterlaceConfiguration failed: %d", rc));
441                }
442#else
443                rc = BVDC_Window_SetDeinterlaceConfiguration(display->disp[id].hVideoWindow, true, &madSettings);
444                if (rc != BERR_SUCCESS) {
445                        BDBG_WRN(("!!!!!! BVDC_Window_SetDeinterlaceConfiguration failed: %d", rc));
446                }
447#endif
448                //BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eBypass );       
449                bdisplay_set_hdmi_output_options(display);
450                BVDC_Window_SetPanScanType(display->disp[id].hVideoWindow,BVDC_PanScanType_eStream);
451                BVDC_Window_SetBandwidthEquationParams(display->disp[id].hVideoWindow, 1000000, BVDC_SclCapBias_eSclBeforeCap);
452        }
453        else
454#endif  //HAS_HDMI
455        {
456#ifdef SHRINK_WIDTH
457                display->settings.shrink_width = true;
458                madSettings.bShrinkWidth = display->settings.shrink_width;
459
460                BVDC_Window_SetDeinterlaceConfiguration(display->disp[id].hVideoWindow, true, &madSettings);
461#endif
462                /* for SD, just fixed output */
463                //BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eBypass );     
464                bdisplay_set_sd_output_options(display, id, display->settings.sd_options);
465                BVDC_Window_SetPanScanType(display->disp[id].hVideoWindow,BVDC_PanScanType_eDisable);
466        }
467        BVDC_Window_SetScaleFactorRounding(display->disp[id].hVideoWindow, 3, 3);
468        rc = BVDC_ApplyChanges(display->hVdc);
469        if (rc != BERR_SUCCESS)
470        {
471                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
472        }
473        return rc;
474error:
475        bdisplay_video_window_close(display,id);
476        return rc;
477}
478
479/* because we couldn't enable MAD for both output simultaneously,
480 * should disable MAD for one path to enable deinterlacer for the other path
481 */
482void bdisplay_set_deinterlacer(bdisplay_t display, int id, bool enable)
483{
484        bsettop_display_id_t alt_id;
485        BVDC_Deinterlace_Settings madSettings;
486        bool deinterlace;
487        BERR_Code rc;
488
489        b_lock_vdc();
490#if HAS_HDMI
491        alt_id = (id == eBDISPLAY_HDMI)?eBDISPLAY_COMPOSITE:eBDISPLAY_HDMI;
492#else
493        alt_id = eBDISPLAY_COMPOSITE;
494#endif
495
496        BVDC_Window_GetDeinterlaceConfiguration(display->disp[alt_id].hVideoWindow, &deinterlace, &madSettings);
497#if (BCHP_CHIP==7552)
498        madSettings.stVideoTestFeature1.bEnable = true;
499        madSettings.stVideoTestFeature1.ulBitsPerPixel = 18;
500#endif
501        rc = BVDC_Window_SetDeinterlaceConfiguration(display->disp[alt_id].hVideoWindow, false, &madSettings);
502        if (rc != BERR_SUCCESS) {
503                BDBG_WRN(("%s: BVDC_Window_SetDeinterlaceConfiguration failed: %d", __FUNCTION__, rc));
504                b_unlock_vdc();
505                return;
506        }
507        BVDC_ApplyChanges(display->hVdc);
508
509        BVDC_Window_GetDeinterlaceConfiguration(display->disp[id].hVideoWindow, &deinterlace, &madSettings);
510#ifdef SHRINK_WIDTH
511                if ( (display->hdmiFmt!=BFMT_VideoFmt_e1080p_24Hz) && (display->hdmiFmt!=BFMT_VideoFmt_e1080p_30Hz) && (display->hdmiFmt != BFMT_VideoFmt_e1080p))
512                { 
513                        madSettings.bShrinkWidth = display->settings.shrink_width;
514
515                }
516#endif
517#if (BCHP_CHIP==7552)
518        madSettings.stVideoTestFeature1.bEnable = true;
519        madSettings.stVideoTestFeature1.ulBitsPerPixel = 18;
520#endif
521        rc = BVDC_Window_SetDeinterlaceConfiguration(display->disp[id].hVideoWindow, enable, &madSettings);
522        if (rc != BERR_SUCCESS) {       
523                BDBG_WRN(("%s: BVDC_Window_SetDeinterlaceConfiguration failed: %d", __FUNCTION__, rc)); 
524                b_unlock_vdc();
525                return;
526        }
527        BVDC_ApplyChanges(display->hVdc);
528        b_unlock_vdc();
529}
530
531/* set the sharpness/softness for SD SCL
532 * coeff_idx: 1 (softness) -> 26 (sharpness)
533 */
534void bdisplay_set_coefficient_index(bdisplay_t display,bool horiz, int output, int coeff_idx)
535{
536        BERR_Code rc;
537        BVDC_CoefficientIndex index;
538#if HAS_HDMI
539        int id = (output == 0) ? eBDISPLAY_HDMI : eBDISPLAY_COMPOSITE;
540#else
541        int id = eBDISPLAY_COMPOSITE;
542#endif
543        BKNI_Memset(&index, 0, sizeof(index));
544
545        b_lock_vdc();   
546        if (horiz)
547        {
548                /* VDC takes 101 to 126 for index value instead of 1 to 26 */
549                index.ulSclHorzLuma = index.ulSclHorzChroma = coeff_idx + 100;
550        }
551        else
552        {
553                index.ulSclVertLuma  = index.ulSclVertChroma = coeff_idx + 100;
554        }
555               
556        rc = BVDC_Window_SetCoefficientIndex(display->disp[id].hVideoWindow, &index);
557        if (rc != BERR_SUCCESS) {
558                BKNI_Memset(&index, 0, sizeof(index));
559                BVDC_Window_SetCoefficientIndex(display->disp[id].hVideoWindow, &index);
560        }       
561        rc = BVDC_ApplyChanges(display->hVdc);
562        if (rc != BERR_SUCCESS) {
563                BDBG_WRN(("Fail to set SCL coefficient:%d", rc));
564        }       
565        b_unlock_vdc();
566}
567
568/**
569Summary:
570  Allocate and reserve resources for a display pipeline. Expects
571  allocated bapp_nexus_t structure.
572**/
573static BERR_Code bdisplay_display_close(bdisplay_t display,  bsettop_display_id_t id)
574{
575        BERR_Code rc;
576#if HAS_HDMI
577        BVDC_Display_CallbackSettings displayCBSettings;
578#endif
579
580        BDBG_ASSERT(display);
581#ifdef CONFIG_NO_SD_OUTPUT
582        if (id == eBDISPLAY_COMPOSITE)
583                return BERR_SUCCESS;
584#endif
585
586#if 0
587        if (display->disp[id].vsyncCbHandle)
588        {
589                BINT_DisableCallback(display->disp[id].vsyncCbHandle);
590                BINT_DestroyCallback(display->disp[id].vsyncCbHandle);
591                display->disp[id].vsyncCbHandle = NULL;
592        }
593#endif
594
595#if HAS_HDMI
596    if (id == eBDISPLAY_HDMI)
597    {
598        BVDC_Display_GetCallbackSettings(display->disp[id].hDisplay, &displayCBSettings);
599        displayCBSettings.stMask.bRateChange=0;
600        BVDC_Display_SetCallbackSettings(display->disp[id].hDisplay, &displayCBSettings);
601        rc = BVDC_Display_InstallCallback(display->disp[id].hDisplay,
602                (BVDC_CallbackFunc_isr)NULL, display, 0);
603    }
604#endif
605        if (id == eBDISPLAY_COMPOSITE)
606        { 
607                bdisplay_p_vbi_disconnect(display);
608                bdisplay_p_vbi_close(display);
609        }       
610
611        if (display->disp[id].hDisplay)
612        {
613                BVDC_Display_Destroy(display->disp[id].hDisplay);
614                display->disp[id].hDisplay = NULL;
615        }
616        if (display->disp[id].hCmp)
617        {
618                BVDC_Compositor_Destroy(display->disp[id].hCmp);
619                display->disp[id].hCmp = NULL;
620        }
621        rc = BVDC_ApplyChanges(display->hVdc);
622        if (rc != BERR_SUCCESS)
623        {
624                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
625        }
626        return BERR_SUCCESS;
627}
628
629/**
630Summary:
631  Allocate and reserve resources for a display pipeline. Expects
632  allocated bapp_nexus_t structure.
633**/
634static BERR_Code bdisplay_display_open(bdisplay_t display,  bsettop_display_id_t id)
635{
636        BERR_Code rc;
637#ifdef HAS_HDMI
638        BVDC_Display_CallbackSettings displayCBSettings;
639#endif
640
641        BDBG_ASSERT(display);
642#ifdef CONFIG_NO_SD_OUTPUT
643        if (id == eBDISPLAY_COMPOSITE)
644                return BERR_SUCCESS;
645#endif
646
647        rc = BVDC_Compositor_Create(display->hVdc, &(display->disp[id].hCmp), 
648                                                                BVDC_CompositorId_eCompositor0 + id, NULL);
649        if (rc != BERR_SUCCESS)
650        {
651                BDBG_ERR(("BVDC_Compositor_Create failed %d\n", rc));
652                goto error;
653        }
654
655        rc = BVDC_Display_Create( display->disp[id].hCmp, &(display->disp[id].hDisplay), 
656                                                          BVDC_DisplayId_eAuto,NULL);
657        if (rc != BERR_SUCCESS)
658        {
659                BDBG_ERR(("BVDC_Display_Create failed %d\n", rc));
660                goto error;
661        }
662
663        rc = BVDC_Display_SetTimebase(display->disp[id].hDisplay, BAVC_Timebase_e0);/* XXX Set proper timebase BAVC_Timebase_e0 */
664        if (rc != BERR_SUCCESS)
665        {
666                BDBG_ERR(("BVDC_Display_SetTimebase failed %d\n", rc));
667        }
668
669#if HAS_HDMI
670        if (id == eBDISPLAY_HDMI)
671        {
672                BVDC_Display_SetVideoFormat(display->disp[id].hDisplay, display->hdmiFmt);
673
674                BVDC_Display_GetCallbackSettings(display->disp[id].hDisplay, &displayCBSettings);
675                displayCBSettings.stMask.bRateChange=1;
676                BVDC_Display_SetCallbackSettings(display->disp[id].hDisplay, &displayCBSettings);
677                rc = BVDC_Display_InstallCallback(display->disp[id].hDisplay,
678                                                                                  (BVDC_CallbackFunc_isr)bdisplay_rate_change_cb,
679                                                                                  display, 0);
680                if (rc != BERR_SUCCESS)
681                {
682                        BDBG_ERR(("BVDC_Display_InstallCallback failed %d\n", rc));
683                }
684#ifndef HDMI_SD_WIDE_SCREEN
685                if ((display->hdmiFmt == BFMT_VideoFmt_e480p) || (display->hdmiFmt == BFMT_VideoFmt_eNTSC))
686                {
687                        rc = BVDC_Display_SetAspectRatio(display->disp[id].hDisplay, BFMT_AspectRatio_e4_3);
688                }
689                else
690                {
691                        rc = BVDC_Display_SetAspectRatio(display->disp[id].hDisplay, BFMT_AspectRatio_e16_9);
692                }
693#else
694                rc = BVDC_Display_SetAspectRatio(display->disp[id].hDisplay, BFMT_AspectRatio_e16_9);
695#endif
696                if (rc != BERR_SUCCESS)
697                {
698                        BDBG_ERR(("BVDC_Display_SetAspectRatio failed %d\n", rc));
699                }
700        }
701        else
702#endif
703        {
704                rc = BVDC_Display_SetVideoFormat(display->disp[id].hDisplay, BFMT_VideoFmt_eNTSC);
705                if (rc != BERR_SUCCESS)
706                {
707                        BDBG_ERR(("BVDC_Display_SetVideoFormat failed %d\n", rc));
708                }
709#if (!defined(ACB612) && !defined(ACB615))
710#ifdef BCHP_MISC_DAC_0_CFG_SEL_GRPD_0_CVBS
711                rc = BVDC_Display_SetDacConfiguration( display->disp[id].hDisplay, BVDC_Dac_0, BVDC_DacOutput_eFilteredCvbs);
712#else
713                rc = BVDC_Display_SetDacConfiguration( display->disp[id].hDisplay, BVDC_Dac_0, BVDC_DacOutput_eComposite);
714#endif
715#else
716                rc = BVDC_Display_SetDacConfiguration( display->disp[id].hDisplay, BVDC_Dac_0, BVDC_DacOutput_eComposite);
717#endif
718                if (rc != BERR_SUCCESS)
719                {
720                        BDBG_ERR(("BVDC_Display_SetDacConfiguration failed %d\n", rc));
721                }
722
723                rc = BVDC_Display_SetAspectRatio(display->disp[id].hDisplay, BFMT_AspectRatio_e4_3);
724                if (rc != BERR_SUCCESS)
725                {
726                        BDBG_ERR(("BVDC_Display_SetAspectRatio failed %d\n", rc));
727                }
728        }
729
730#if 0
731        rc = BVDC_Compositor_SetBackgroundColor(display->disp[id].hCmp, 0xFF, 0, 0);
732        BDBG_ASSERT(rc == BERR_SUCCESS);
733#endif
734#if 0
735
736        rc = BINT_CreateCallback(&(display->disp[id].vsyncCbHandle), GetINT(), intId, bdisplay_vsync_isr, display, id);
737        if (rc) return BERR_TRACE(rc);
738        rc = BINT_EnableCallback(display->disp[id].vsyncCbHandle);
739        if (rc) return BERR_TRACE(rc);
740#endif
741
742        /* connect vbi encoder to the composite output */
743        if (id == eBDISPLAY_COMPOSITE){
744                rc = bdisplay_p_vbi_open(display);
745                if (rc != BERR_SUCCESS) {
746                        BDBG_ERR(("Fail to open VBI %d", rc));
747                }
748                else {
749                        rc = bdisplay_p_vbi_connect(display);
750                        if (rc != BERR_SUCCESS) {
751                                BDBG_ERR(("Fail to connect VBI %d", rc));
752                        }
753                }
754        }
755
756        rc = BVDC_ApplyChanges(display->hVdc);
757        if (rc != BERR_SUCCESS)
758        {
759                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
760        }
761        return BERR_SUCCESS;
762error:
763        bdisplay_display_close(display,id);
764        return rc;
765}
766
767/**
768Summary:
769Allocate and reserve resources.  Expects allocated bapp_nexus_t structure.
770 **/
771static BERR_Code bdisplay_vdc_close(bdisplay_t display)
772{
773        BERR_Code rc;
774        BDBG_ASSERT(display);
775#if HAS_HDMI
776        rc = bdisplay_video_window_close(display,eBDISPLAY_HDMI);
777        {
778                BDBG_ERR(("bdisplay_video_window_close failed %d\n", rc));
779        }
780#endif
781        rc = bdisplay_video_window_close(display,eBDISPLAY_COMPOSITE);
782        {
783                BDBG_ERR(("bdisplay_video_window_close failed %d\n", rc));
784        }
785#if HAS_HDMI
786        rc = bdisplay_graphics_window_close(display,eBDISPLAY_HDMI);
787        {
788                BDBG_ERR(("bdisplay_graphics_window_close failed %d\n", rc));
789        }
790#endif
791        rc = bdisplay_graphics_window_close(display,eBDISPLAY_COMPOSITE);
792        {
793                BDBG_ERR(("bdisplay_graphics_window_close failed %d\n", rc));
794        }
795
796#if HAS_HDMI
797        rc = bdisplay_display_close(display,eBDISPLAY_HDMI);
798        if (rc != BERR_SUCCESS)
799        {
800                BDBG_ERR(("bdisplay_display_close failed %d\n", rc));
801        }
802#endif
803        rc = bdisplay_display_close(display,eBDISPLAY_COMPOSITE);
804        if (rc != BERR_SUCCESS)
805        {
806                BDBG_ERR(("bdisplay_display_close failed %d\n", rc));
807        }
808
809        if (display->hVideoSource)
810        {
811                rc = BVDC_Source_Destroy(display->hVideoSource);
812                if (rc != BERR_SUCCESS)
813                {
814                        BDBG_ERR(("BVDC_Source_Create failed %d\n", rc));
815                }
816        }
817
818        if (display->hVdc)
819        {
820                rc = BVDC_Close(display->hVdc);
821                if (rc != BERR_SUCCESS)
822                {
823                        BDBG_ERR(("BVDC_Open failed %d\n", rc));
824                }
825        }
826
827        if (display->hRdc)
828        {
829                rc = BRDC_Close(display->hRdc);
830                if (rc != BERR_SUCCESS)
831                {
832                        BDBG_ERR(("BRDC_Open failed %d\n", rc));
833                }
834        }
835
836        display->hVideoSource = NULL;
837        display->hVdc = NULL;
838        display->hRdc = NULL;
839
840        rc = BVDC_ApplyChanges(display->hVdc);
841        if (rc != BERR_SUCCESS)
842        {
843                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
844        }
845        return BERR_SUCCESS;
846}
847
848/**
849Summary:
850Allocate and reserve resources.  Expects allocated bapp_nexus_t structure.
851 **/
852static BERR_Code bdisplay_vdc_open(bdisplay_t display)
853{
854        BERR_Code rc;
855        BRDC_Settings rdcSettings;
856        BVDC_Settings vdcSettings;
857        BINT_Id  TopInterruptName;
858        BINT_Id  BotInterruptName;
859        BINT_Id  ProgressiveInterruptName;
860        BDBG_ASSERT(display);
861
862        /*
863           BDBG_SetModuleLevel("bvdc", BDBG_eMsg) ;
864           BDBG_SetModuleLevel("bvdc_window", BDBG_eMsg) ;
865           BDBG_SetModuleLevel("bvdc_window_priv", BDBG_eMsg) ;
866         */
867
868        rc = BRDC_GetDefaultSettings(GetCHP(),&rdcSettings);
869        BDBG_ASSERT(rc == BERR_SUCCESS);
870        rc = BRDC_Open(&(display->hRdc), GetCHP(),GetREG(),GetHEAP(),&rdcSettings);
871        if (rc != BERR_SUCCESS)
872        {
873                BDBG_ERR(("BRDC_Open failed %d\n", rc));
874                goto error;
875        }
876
877        BVDC_GetDefaultSettings(&vdcSettings);
878#ifdef SHRINK_WIDTH
879        /* adjust heap memory for using ShrinkWidth feature */
880        vdcSettings.stHeapSettings.ulBufferCnt_2HD_Pip += 6;
881        vdcSettings.stHeapSettings.ulBufferCnt_SD -= 6;
882#endif
883
884#if (BCHP_CHIP==7552)
885#if defined(ACB612)     /* HD only, 1080p@60 */
886        /* 2HD__Pip default is 0 */
887        vdcSettings.stHeapSettings.ulBufferCnt_2HD_Pip = 1;
888        /* 2HD default is 0 */
889        vdcSettings.stHeapSettings.ulBufferCnt_2HD = 2;
890        /* HD default is 4 */
891        vdcSettings.stHeapSettings.ulBufferCnt_HD = 3;
892        /* SD default is 18 */
893        //vdcSettings.stHeapSettings.ulBufferCnt_SD += 4;       
894        vdcSettings.stHeapSettings.ulBufferCnt_SD = 0;
895#else
896        vdcSettings.stHeapSettings.ulBufferCnt_2HD_Pip = 2;
897        vdcSettings.stHeapSettings.ulBufferCnt_2HD += 6;
898        vdcSettings.stHeapSettings.ulBufferCnt_SD += 4; 
899#endif
900
901#if defined(ACB615)
902        /* SD and HD,  1080p@60 */
903        vdcSettings.stHeapSettings.ulBufferCnt_2HD += 1;
904        vdcSettings.stHeapSettings.ulBufferCnt_SD = 4;
905#endif
906
907#else
908        vdcSettings.stHeapSettings.ulBufferCnt_SD = 6;
909        vdcSettings.stHeapSettings.ulBufferCnt_HD = 10;
910#endif
911        /* Modify BandGapAdjust if necessary */
912        {
913                int id;
914
915                for(id = 0; id < BVDC_MAX_DACS; id++)
916                {
917                        if (vdcSettings.aulDacBandGapAdjust[id])
918                        {
919                                /* currently 26, change to 27 to boost it */
920#if (BCHP_CHIP!=7552)
921#ifdef IREF_ADJ_0x10
922#warning "Special tuning: MISC_DAC_BG_CTRL_0.IREF_ADJ = 0x10"
923                                vdcSettings.aulDacBandGapAdjust[id] = 0x10;
924#else
925                                vdcSettings.aulDacBandGapAdjust[id] = BCHP_MISC_DAC_BG_CTRL_0_IREF_ADJ_TWENTY_SEVEN;
926#endif
927#endif
928                        }
929                }
930        }       
931
932        rc = BVDC_Open(&(display->hVdc), GetCHP(),GetREG(),GetHEAP(),GetINT(),display->hRdc,GetTMR(),&vdcSettings);
933        if (rc != BERR_SUCCESS)
934        {
935                BDBG_ERR(("BVDC_Open failed %d\n", rc));
936                goto error;
937        }
938
939        rc = BVDC_ApplyChanges(display->hVdc);
940        if (rc != BERR_SUCCESS)
941        {
942                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
943        }
944
945        rc = BVDC_Source_Create(display->hVdc,&(display->hVideoSource),BAVC_SourceId_eMpeg0,NULL);
946        if (rc != BERR_SUCCESS)
947        {
948                BDBG_ERR(("BVDC_Source_Create failed %d\n", rc));
949                goto error;
950        }
951
952        //BVDC_Source_SetVideoMuteColor(display->hVideoSource,0x00,0xFF,0x00);
953
954//RLQ
955#if HAS_HDMI
956        /* Open display pipelines */
957        rc = bdisplay_display_open(display,eBDISPLAY_HDMI);
958        if (rc != BERR_SUCCESS)
959        {
960                BDBG_ERR(("bdisplay_display_open failed %d\n", rc));
961                goto error;
962        }
963#endif
964        rc = bdisplay_display_open(display,eBDISPLAY_COMPOSITE);
965        if (rc != BERR_SUCCESS)
966        {
967                BDBG_ERR(("bdisplay_display_open failed %d\n", rc));
968                goto error;
969        }
970
971        rc = BVDC_Source_GetInterruptName(display->hVideoSource,BAVC_Polarity_eTopField,&TopInterruptName);
972        BDBG_ASSERT(rc == BERR_SUCCESS);
973        rc = BVDC_Source_GetInterruptName(display->hVideoSource,BAVC_Polarity_eBotField,&BotInterruptName);
974        BDBG_ASSERT(rc == BERR_SUCCESS);
975        rc = BVDC_Source_GetInterruptName(display->hVideoSource,BAVC_Polarity_eFrame,&ProgressiveInterruptName);
976        BDBG_ASSERT(rc == BERR_SUCCESS);
977
978        rc = BXVD_RegisterVdcInterrupt(GetXVDCh(),TopInterruptName,BAVC_Polarity_eTopField);
979        BDBG_ASSERT(rc == BERR_SUCCESS);
980        rc = BXVD_RegisterVdcInterrupt(GetXVDCh(),BotInterruptName,BAVC_Polarity_eBotField);
981        BDBG_ASSERT(rc == BERR_SUCCESS);
982        rc = BXVD_RegisterVdcInterrupt(GetXVDCh(),ProgressiveInterruptName,BAVC_Polarity_eFrame);
983        BDBG_ASSERT(rc == BERR_SUCCESS);
984
985        rc = BXVD_InstallInterruptCallback(GetXVDCh(),BXVD_Interrupt_ePictureDataReady,
986                        MpegDataReady_isr,display->hVideoSource, 0 );
987        BDBG_ASSERT(rc == BERR_SUCCESS);
988
989        rc = BVDC_ApplyChanges(display->hVdc);
990        if (rc != BERR_SUCCESS)
991        {
992                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
993        }
994#if HAS_HDMI
995        rc = bdisplay_video_window_open(display,eBDISPLAY_HDMI);
996        if (rc != BERR_SUCCESS)
997        {
998                BDBG_ERR(("bdisplay_video_window_open (HDMI) failed %d\n", rc));
999                goto error;
1000        }
1001#endif
1002        rc = bdisplay_video_window_open(display,eBDISPLAY_COMPOSITE);
1003        if (rc != BERR_SUCCESS)
1004        {
1005                BDBG_ERR(("bdisplay_video_window_open (COMPOSITE) failed %d\n", rc));
1006                goto error;
1007        }
1008
1009        return BERR_SUCCESS;
1010error:
1011        bdisplay_vdc_close(display);
1012        return rc;
1013}
1014
1015
1016/**
1017Summary:
1018Allocate and reserve resources.  Expects allocated bapp_nexus_t structure.
1019 **/
1020static BERR_Code bdisplay_format_change(bdisplay_t display,
1021                BFMT_VideoFmt format)
1022{
1023        BERR_Code rc;
1024        BFMT_VideoFmt original_format;
1025        BDBG_ASSERT(display);
1026        if (format == display->hdmiFmt)
1027                return BERR_SUCCESS;
1028
1029        original_format = display->hdmiFmt;
1030
1031        rc = bdisplay_video_window_close(display,eBDISPLAY_COMPOSITE);
1032        if (rc != BERR_SUCCESS)
1033        {
1034                BDBG_ERR(("bdisplay_video_window_close failed %d\n", rc));
1035                goto error;
1036        }
1037
1038        rc = bdisplay_graphics_window_close(display,eBDISPLAY_COMPOSITE);
1039        if (rc != BERR_SUCCESS)
1040        {
1041                BDBG_ERR(("bdisplay_graphics_window_close failed %d\n", rc));
1042                goto error;
1043        }
1044
1045#if HAS_HDMI
1046        rc = bdisplay_video_window_close(display,eBDISPLAY_HDMI);
1047        if (rc != BERR_SUCCESS)
1048        {
1049                BDBG_ERR(("bdisplay_video_window_close failed %d\n", rc));
1050                goto error;
1051        }
1052        rc = bdisplay_graphics_window_close(display,eBDISPLAY_HDMI);
1053        if (rc != BERR_SUCCESS)
1054        {
1055                BDBG_ERR(("bdisplay_graphics_window_close failed %d\n", rc));
1056                goto error;
1057        }
1058        rc = bdisplay_display_close(display,eBDISPLAY_HDMI);
1059        if (rc != BERR_SUCCESS)
1060        {
1061                BDBG_ERR(("bdisplay_display_close failed %d\n", rc));
1062                goto error;
1063        }
1064#endif
1065
1066        display->hdmiFmt = format;
1067
1068#if HAS_HDMI
1069        rc = bdisplay_display_open(display,eBDISPLAY_HDMI);
1070        if (rc != BERR_SUCCESS)
1071        {
1072                BDBG_ERR(("bdisplay_display_open failed %d\n", rc));
1073                goto error;
1074        }
1075#endif
1076
1077#if HAS_HDMI
1078        rc = BVDC_Display_SetVideoFormat(display->disp[eBDISPLAY_HDMI].hDisplay, format);
1079        if (rc != BERR_SUCCESS)
1080        {
1081                BDBG_ERR(("bdisplay_display_open failed %d\n", rc));
1082                goto error;
1083        }
1084
1085#ifndef HDMI_SD_WIDE_SCREEN
1086        if ((display->hdmiFmt == BFMT_VideoFmt_e480p) || (display->hdmiFmt == BFMT_VideoFmt_eNTSC))
1087        {
1088                rc = BVDC_Display_SetAspectRatio(display->disp[eBDISPLAY_HDMI].hDisplay, BFMT_AspectRatio_e4_3);
1089        }
1090        else
1091        {
1092                rc = BVDC_Display_SetAspectRatio(display->disp[eBDISPLAY_HDMI].hDisplay, BFMT_AspectRatio_e16_9);
1093        }
1094        if (rc != BERR_SUCCESS)
1095        {
1096                BDBG_ERR(("BVDC_Display_SetAspectRatio failed %d\n", rc));
1097                goto error;
1098        }
1099#endif
1100
1101        rc = bdisplay_video_window_open(display,eBDISPLAY_HDMI);
1102        if (rc != BERR_SUCCESS)
1103        {
1104                bdisplay_display_close(display,eBDISPLAY_HDMI);
1105                BDBG_ERR(("bdisplay_video_window_open failed %d\n", rc));
1106                goto error;
1107        }
1108
1109        rc = bdisplay_graphics_window_open(display,eBDISPLAY_HDMI);
1110        if (rc != BERR_SUCCESS)
1111        {
1112                bdisplay_video_window_close(display,eBDISPLAY_HDMI);
1113                bdisplay_display_close(display,eBDISPLAY_HDMI);
1114                BDBG_ERR(("bdisplay_graphics_window_open failed %d\n", rc));
1115                goto error;
1116        }
1117#endif
1118
1119#ifndef CONFIG_NO_SD_OUTPUT
1120        rc = bdisplay_video_window_open(display,eBDISPLAY_COMPOSITE);
1121        if (rc != BERR_SUCCESS)
1122        {
1123                BDBG_ERR(("bdisplay_video_window_open failed %d\n", rc));
1124                goto error;
1125        }
1126
1127        rc = bdisplay_graphics_window_open(display,eBDISPLAY_COMPOSITE);
1128        if (rc != BERR_SUCCESS)
1129        {
1130                BDBG_ERR(("bdisplay_video_window_open failed %d\n", rc));
1131                goto error;
1132        }
1133#endif
1134        return BERR_SUCCESS;
1135
1136error:
1137        display->hdmiFmt = original_format;
1138#if HAS_HDMI
1139        BVDC_Display_SetVideoFormat(display->disp[eBDISPLAY_HDMI].hDisplay, original_format);
1140        rc = bdisplay_display_open(display,eBDISPLAY_HDMI);
1141        if (rc != BERR_SUCCESS)
1142        {
1143                BDBG_ERR(("bdisplay_display_open failed %d\n", rc));
1144        }
1145        rc = bdisplay_video_window_open(display,eBDISPLAY_HDMI);
1146        if (rc != BERR_SUCCESS)
1147        {
1148                BDBG_ERR(("bdisplay_video_window_open failed %d\n", rc));
1149        }
1150        rc = bdisplay_graphics_window_open(display,eBDISPLAY_HDMI);
1151        if (rc != BERR_SUCCESS)
1152        {
1153                BDBG_ERR(("bdisplay_graphics_window_open (HDMI) failed %d\n", rc));
1154        }
1155#endif
1156        return BERR_UNKNOWN;
1157}
1158#ifdef CONFIG_RFM
1159static bresult
1160boutput_p_rf_set(
1161                boutput_rf_t rf,        /* handle returned by boutput_rf_open */
1162                boutput_rf_settings *settings   /* desired rf settings */
1163                )
1164{
1165        BRFM_OutputChannel rf_out;
1166        BRFM_ModulationType modType;
1167
1168        if (settings->channel == eRFM_CH4)
1169                rf_out = BRFM_OutputChannel_eCh4;
1170        else
1171                rf_out = BRFM_OutputChannel_eCh3;
1172
1173        switch ( (uint16_t)settings->country[0] << 8 | (uint16_t)settings->country[1] )
1174        {
1175                default:
1176                        BDBG_WRN(("Unsupported country ! Using Ntsc Open Cable"));
1177                case COUNTRY_CODE('U','S'):
1178                        modType = BRFM_ModulationType_eNtscOpenCable;
1179                        break;
1180                case COUNTRY_CODE('C','N'):
1181                        modType = BRFM_ModulationType_ePalDChina;
1182                        break;
1183        }
1184
1185        if (rf->handle == NULL)
1186        {
1187                BRFM_Settings rfm_cfg;
1188
1189                BRFM_GetDefaultSettings(&rfm_cfg, 1);
1190
1191#ifdef BQAM_SCRIPT
1192                rfm_cfg.audioEncoding = BRFM_AudioEncoding_eStereo;
1193#else
1194                rfm_cfg.audioEncoding = BRFM_AudioEncoding_eMono;
1195#endif
1196                rfm_cfg.chNbr = rf_out;
1197
1198                if (BRFM_Open(&rf->handle, 1, 1, 1, &rfm_cfg) != BERR_SUCCESS)
1199                {
1200                        BDBG_ERR(("%s: BRFM_Open failed\n", __FUNCTION__));
1201                        return berr_invalid_parameter;
1202                }
1203        }
1204
1205        if (BRFM_SetModulationType(rf->handle, modType, rf_out) != BERR_SUCCESS)
1206        {
1207                BDBG_ERR(("%s: BRFM_SetModulationType failed\n", __FUNCTION__));
1208                return berr_invalid_parameter;
1209        }
1210
1211        if (settings->enable_output)
1212        {
1213                if (BRFM_EnableRfOutput(rf->handle) != BERR_SUCCESS)
1214                {
1215                        BDBG_ERR(("%s: BRFM_EnableRfOutput failed\n", __FUNCTION__));
1216                        return berr_external_error;
1217                }
1218        }
1219        else
1220        {
1221                if (BRFM_DisableRfOutput(rf->handle) != BERR_SUCCESS)
1222                {
1223                        BDBG_ERR(("%s: BRFM_DisableRfOutput failed\n", __FUNCTION__));
1224                        return berr_external_error;
1225                }
1226        }
1227        rf->update = false;
1228        SW_TRACE_SET(SW_TRACE_RFM_INIT);
1229        return b_ok;
1230}
1231
1232/*
1233Summary:
1234set RFM volume
1235 */
1236static bresult
1237boutput_p_rf_volume_set (
1238                boutput_rf_t rf,
1239                unsigned int volume       /* with RFM volume to set */
1240                )
1241{
1242        int vol;
1243
1244        if (rf->handle == NULL)
1245        {
1246                return berr_invalid_parameter;
1247        }
1248
1249        BDBG_MSG(("%s: RFM volume=%d\n", __FUNCTION__, volume));
1250
1251        /* validate range, normalized to 0 - 100 */
1252        if (volume < 0 || volume > 100)
1253                return berr_invalid_parameter;
1254
1255        /* convert volume to dB based value (-34 - 30) */
1256        vol = (volume * (MX_VOLUME - MN_VOLUME)) / 100 + MN_VOLUME;
1257        if (BRFM_SetAudioVolume(rf->handle, vol))
1258                return berr_invalid_parameter;
1259
1260        rf->volume = volume;
1261        return b_ok;
1262}
1263#endif
1264
1265#ifdef CONFIG_SPDIF
1266static bresult
1267boutput_p_spdif_set(
1268                boutput_spdif_t spdif,  /* handle returned by boutput_spdif_open */
1269                boutput_spdif_settings *settings           /* desired spdif settings */
1270                )
1271{
1272
1273        spdif->update = false;
1274        return b_ok;
1275}
1276#endif
1277
1278#ifdef CONFIG_I2S
1279static bresult
1280boutput_p_i2s_set(
1281                boutput_i2s_t i2s,       /* handle returned by boutput_i2s_open */
1282                boutput_i2s_settings *settings   /* desired i2s settings */
1283                )
1284{
1285        return b_ok;
1286}
1287#endif
1288
1289/*
1290Summary:
1291to set initial hdmi video format if not default 720p
1292Description:
1293to set initial hdmi video format if not default 720p
1294 */
1295bresult bdisplay_set_init_format(
1296                bobject_t display_id, /* handle used to identify a particular display */
1297                bsettop_display_format_t settop_fmt
1298                )
1299{
1300#if HAS_HDMI
1301        if (eBDISPLAY_HDMI != display_id) 
1302                return berr_not_supported;
1303#endif
1304
1305        if (bdisplay_format_auto == settop_fmt)
1306                /* likely edid is not available yet */
1307                b_displays[display_id].hdmiFmt = BFMT_VideoFmt_e480p;
1308        else
1309                b_displays[display_id].hdmiFmt = bdisplay_hdmi_format_to_bfmt(settop_fmt);
1310        return b_ok;
1311}
1312
1313/*
1314Summary:
1315Open a display.
1316Description:
1317The new display object will already have default outputs configured.
1318You can change the configuration by calling bdisplay_set, making changes,
1319then calling bdisplay_set.
1320 */
1321bdisplay_t bdisplay_open(
1322                bobject_t display_id /* handle used to identify a particular display */
1323                )
1324{
1325        unsigned int index;
1326        bdisplay_t display;
1327
1328        bos_create_mutex(&b_displays[0].vdc_mutex);
1329
1330        index = B_ID_GET_INDEX(display_id);
1331        if (index >= B_N_DISPLAYS)
1332        {
1333                BDBG_ERR(("%s: Display index %d is invalid!\n", __FUNCTION__, index));
1334                return NULL;
1335        }
1336        display = &b_displays[index];
1337        if (display->open)
1338        {
1339                BDBG_ERR(("%s: Display %d already opened!\n", __FUNCTION__, index));
1340                return NULL;
1341        }
1342
1343#if (defined(ACB612) || defined(ACB615))
1344        display->offscreen = NULL;
1345        display->overlay = NULL;
1346        display->osd = NULL;
1347#ifdef CONFIG_GFX_ARGB32
1348        display->pxl_format = BPXL_eA8_R8_G8_B8;
1349#else
1350        display->pxl_format = BPXL_eP4;
1351#endif
1352        display->surface_idx = eBSURFACE_0;
1353#endif
1354
1355        b_lock_vdc();
1356        if (bdisplay_vdc_open(display) != BERR_SUCCESS)
1357        {
1358                BDBG_ERR(("%s: bdisplay_vdc_open error!\n", __FUNCTION__));
1359                b_unlock_vdc();
1360                return NULL;
1361        }
1362        display->open = true;
1363        b_unlock_vdc();
1364        return display;
1365}
1366
1367/*
1368Summary:
1369Close a display.
1370Description:
1371All decode windows opened or cloned for this display should have already been closed,
1372otherwise you get an inconsistent state.
1373 */
1374void bdisplay_close(
1375                bdisplay_t display /* handle returned by bdisplay_open */
1376                )
1377{
1378        b_lock_vdc();
1379        if (display->open)
1380        {
1381                if (bdisplay_vdc_close(display) != BERR_SUCCESS)
1382                {
1383                        BDBG_ERR(("%s: bdisplay_vdc_open error!\n", __FUNCTION__));
1384                        b_unlock_vdc();
1385                        return;
1386                }
1387
1388                display->open = false;
1389        }
1390        b_unlock_vdc();
1391}
1392
1393/*
1394Summary:
1395Open a RFM output.
1396Description:
1397It must be assigned to a display.
1398 */
1399        boutput_rf_t
1400boutput_rf_open( bobject_t rfmod_id )
1401{
1402#ifdef CONFIG_RFM
1403        unsigned index;
1404
1405        index = B_ID_GET_INDEX(rfmod_id);
1406        if (index!=0)
1407        {
1408                return NULL;
1409        }
1410        return &b_rf_output;
1411#else
1412        BSTD_UNUSED(rfmod_id);
1413        return NULL;
1414#endif
1415}
1416
1417/*
1418Summary:
1419Open a SPDIF audio output.
1420Description:
1421It must be assigned to a display.
1422 */
1423        boutput_spdif_t
1424boutput_spdif_open(bobject_t spdif_id)
1425{
1426#ifdef CONFIG_SPDIF
1427        unsigned index;
1428
1429        index = B_ID_GET_INDEX(spdif_id);
1430        if (index!=0)
1431        {
1432                return NULL;
1433        }
1434        return &b_spdif_output;
1435#else
1436        BSTD_UNUSED(spdif_id);
1437        return NULL;
1438#endif
1439}
1440/*
1441Summary:
1442Open a I2S audio output.
1443Description:
1444It must be assigned to a display.
1445 */
1446        boutput_i2s_t
1447boutput_i2s_open(bobject_t i2s_id)
1448{
1449#ifdef CONFIG_I2S
1450        unsigned index;
1451
1452        index = B_ID_GET_INDEX(i2s_id);
1453        if (index!=0)
1454        {
1455                return NULL;
1456        }
1457        return &b_i2s_output;
1458#else
1459        BSTD_UNUSED(i2s_id);
1460        return NULL;
1461#endif
1462}
1463
1464bresult
1465boutput_rf_set(boutput_rf_t rf, /* handle returned by boutput_rf_open */ 
1466                const boutput_rf_settings *settings)      /* desired rf settings */
1467{
1468#ifdef CONFIG_RFM
1469        rf->update = true;
1470        rf->cfg = *settings;
1471#else
1472        BSTD_UNUSED(rf);
1473        BSTD_UNUSED(settings);
1474#endif
1475        return b_ok;
1476}
1477
1478bresult
1479boutput_spdif_set(
1480                boutput_spdif_t spdif,   /* handle returned by boutput_spdif_open */
1481                const boutput_spdif_settings *settings   /* desired spdif settings */
1482                )
1483{
1484#ifdef CONFIG_SPDIF
1485        spdif->update = true;
1486        spdif->cfg = *settings;
1487#else
1488        BSTD_UNUSED(spdif);
1489        BSTD_UNUSED(settings);
1490#endif
1491        return b_ok;
1492}
1493
1494bresult
1495boutput_i2s_set(
1496                boutput_i2s_t i2s,  /* handle returned by boutput_i2s_open */
1497                const boutput_i2s_settings *settings       /* desired i2s settings */
1498                )
1499{
1500#ifdef CONFIG_I2S
1501        i2s->update = true;
1502        i2s->cfg = *settings;
1503#else
1504        BSTD_UNUSED(i2s);
1505        BSTD_UNUSED(settings);
1506#endif
1507        return b_ok;
1508}
1509
1510void
1511boutput_rf_get(boutput_rf_t rf, /* handle returned by boutput_rf_open */ 
1512                boutput_rf_settings *settings)  /* desired rf settings */
1513{
1514#ifdef CONFIG_RFM
1515        *settings = rf->cfg;
1516#else
1517        BSTD_UNUSED(rf);
1518        BSTD_UNUSED(settings);
1519#endif
1520}
1521
1522void
1523boutput_spdif_get(
1524                boutput_spdif_t spdif,   /* handle returned by boutput_spdif_open */
1525                boutput_spdif_settings *settings         /* desired spdif settings */
1526                )
1527{
1528#ifdef CONFIG_SPDIF
1529        *settings = spdif->cfg;
1530#else
1531        BSTD_UNUSED(spdif);
1532        BSTD_UNUSED(settings);
1533#endif
1534}
1535
1536void
1537boutput_i2s_get(
1538                boutput_i2s_t i2s,         /* handle returned by boutput_i2s_open */
1539                boutput_i2s_settings *settings  /* desired i2s settings */
1540                )
1541{
1542#ifdef CONFIG_I2S
1543        *settings = i2s->cfg;
1544#else
1545        BSTD_UNUSED(i2s);
1546        BSTD_UNUSED(settings);
1547#endif
1548}
1549
1550/*
1551Summary:
1552        to translate bsettop_display_format_t into BFMT_VideoFmt
1553Description:
1554        to translate bsettop_display_format_t into BFMT_VideoFmt
1555        use EDID to resolve bdisplay_format_auto and invalid fmt
1556 */
1557static BFMT_VideoFmt
1558bdisplay_hdmi_format_to_bfmt(bsettop_display_format_t fmt)
1559{
1560        BFMT_VideoFmt  bfmt;
1561
1562        switch (fmt)
1563        {
1564                case bdisplay_format_auto:    bfmt = bdisplay_hdmi_format_auto(); break;
1565                case bdisplay_format_1080i:   bfmt = BFMT_VideoFmt_e1080i; break;
1566                case bdisplay_format_720p:    bfmt = BFMT_VideoFmt_e720p; break;
1567                case bdisplay_format_480i:    bfmt = BFMT_VideoFmt_eNTSC; break;
1568                case bdisplay_format_480p:    bfmt = BFMT_VideoFmt_e480p; break;
1569                case bdisplay_format_1080p60: /*bfmt = BFMT_VideoFmt_e1080p; break;*/
1570                case bdisplay_format_1080p24: /*bfmt = BFMT_VideoFmt_e1080p_24Hz; break;*/
1571                case bdisplay_format_1080p30: /*bfmt = BFMT_VideoFmt_e1080p_30Hz; break;*/
1572                default:                      bfmt = bdisplay_hdmi_format_auto(); break;
1573        }
1574
1575        return bfmt;
1576}
1577
1578
1579static BFMT_VideoFmt
1580bdisplay_hdmi_format_auto()
1581{
1582#if HAS_HDMI
1583        int idx;
1584
1585        for (idx=HDMI_VIDEO_AUTO_FORMAT_NUM-1; idx>=0; idx--)
1586        {
1587                if (bsettop_hdmi_is_video_fmt_supported(s_hdmi_video_auto_format[idx]))
1588                        return bdisplay_hdmi_format_to_bfmt(s_hdmi_video_auto_format[idx]);
1589        }
1590        /* every TV supports 480p, but NOT necessarily 480i */
1591#endif
1592        return BFMT_VideoFmt_e480p;
1593}
1594
1595void
1596bdisplay_record_hdmi_auto_aspect_ratio(
1597        bdisplay_t display,     /* handle returned by bdisplay_open */
1598        uint32_t  auto_hdmi_480i_aspect_ratio,
1599        uint32_t  auto_hdmi_480p_aspect_ratio
1600        )
1601{
1602        display->auto_hdmi_480i_aspect_ratio = (BFMT_AspectRatio) auto_hdmi_480i_aspect_ratio;
1603        display->auto_hdmi_480p_aspect_ratio = (BFMT_AspectRatio) auto_hdmi_480p_aspect_ratio;
1604}
1605
1606
1607bresult
1608bdisplay_set(
1609                bdisplay_t display,     /* handle returned by bdisplay_open */
1610                bdisplay_settings *settings     /* desired display settings */
1611                )
1612{
1613        bresult res = b_ok;
1614#ifdef HAS_HDMI
1615        bool format_change = false;
1616        BFMT_VideoFmt format;
1617#endif
1618
1619        b_lock_vdc();
1620#ifdef CONFIG_RFM
1621        if (settings->rf && settings->rf->update)
1622        {
1623                res = boutput_p_rf_set(settings->rf, &settings->rf->cfg);
1624                if (res == b_ok)
1625                        res = boutput_p_rf_volume_set(settings->rf, settings->rf->volume);
1626        }
1627#endif
1628
1629#ifdef CONFIG_SPDIF
1630        if (res == b_ok)
1631        {
1632                if (settings->spdif && settings->spdif->update)
1633                        res = boutput_p_spdif_set(settings->spdif, &settings->spdif->cfg);
1634        }
1635#endif
1636
1637#ifdef CONFIG_I2S
1638        if (res == b_ok)
1639        {
1640                if (settings->i2s && settings->i2s->update)
1641                        res = boutput_p_i2s_set(settings->i2s, &settings->i2s->cfg);
1642        }
1643#endif
1644
1645#ifdef HAS_HDMI
1646        format = bdisplay_hdmi_format_to_bfmt(settings->format);
1647
1648        // 1). if settings->format == display->settings.format == bdisplay_format_auto,
1649        // display->hdmiFmt might be the initialized value BFMT_VideoFmt_e720p, and
1650        // might be diff from format = bdisplay_hdmi_format_auto()
1651        // 2). can not call bdisplay_format_change before gfx src is created.
1652        if ((format != display->hdmiFmt) && (display->disp[eBDISPLAY_HDMI].hGfxSource))
1653        {
1654                res = bdisplay_format_change(display,format);
1655                format_change = true;
1656        }
1657#endif
1658        if (settings->sd_options != display->settings.sd_options) {
1659                res = bdisplay_set_sd_output_options(display, eBDISPLAY_COMPOSITE, settings->sd_options);
1660        }
1661#ifdef HAS_HDMI
1662        format = bdisplay_hdmi_format_to_bfmt(settings->format);
1663        if ((settings->hd_options != display->settings.hd_options) || 
1664                (settings->hd_options == bdisplay_hd_output_options_auto) ||
1665                (format_change))
1666        {
1667                display->settings.hd_options = settings->hd_options;
1668                bdisplay_set_hdmi_output_options(display);
1669        }
1670        /* bdisplay_set_graphics_sharpness only works when pxl_format ==  BPXL_eP4 */
1671        if (settings->format < bdisplay_format_720p && (settings->sharpness != display->settings.sharpness)) {
1672                res = bdisplay_set_graphics_sharpness(display, eBDISPLAY_HDMI, settings->sharpness);
1673        }
1674
1675        if ((settings->deinterlace != display->settings.deinterlace) ||
1676                        (settings->shrink_width != display->settings.shrink_width) ||
1677                        (settings->deinterlacer_affinity != display->settings.deinterlacer_affinity))
1678        {
1679                display->settings.shrink_width = settings->shrink_width;
1680                bdisplay_set_deinterlacer(display,settings->deinterlacer_affinity,settings->deinterlace);
1681        }
1682#endif
1683        display->settings = *settings;
1684
1685#if HAS_HDMI
1686        if ((format_change || display->settings.force_change_format) && display->settings.rate_change_cb)
1687        {
1688                display->settings.force_change_format = false;
1689                display->settings.rate_change_cb(display,display->settings.rate_change_data,NULL);
1690                BDBG_ERR(("%s: done!\n", __func__));
1691        }
1692        b_unlock_vdc();
1693#endif
1694
1695        return res;
1696}
1697
1698/*
1699Summary:
1700Get the current outputs, video format and aspect ratio for a display.
1701 */
1702void
1703bdisplay_get(
1704                bdisplay_t display,     /* handle returned by bdisplay_open */
1705                bdisplay_settings *settings     /* [out] current settings of display */
1706                )
1707{
1708        *settings = display->settings;
1709}
1710
1711/*
1712Summary:
1713Set the audio volume for the rf modulator.
1714Description:
1715This function only sets audio volume.
1716 */
1717bresult boutput_rf_set_audio_volume(
1718                boutput_rf_t rf,
1719                unsigned int volume /* desired volume */
1720                )
1721{
1722        bresult res = b_ok;
1723
1724#ifdef CONFIG_RFM
1725        if (rf->handle == NULL)
1726        {
1727                BDBG_ERR(("%s: RF not already opened!\n", __FUNCTION__));
1728                return berr_invalid_parameter;
1729        }
1730
1731        res = boutput_p_rf_volume_set(rf, volume);
1732        if (res == b_ok)
1733        {
1734                rf->volume = volume;
1735        }
1736#else
1737        BSTD_UNUSED(rf);
1738        BSTD_UNUSED(volume);
1739#endif
1740        return res;
1741}
1742
1743/*
1744Summary:
1745Get the audio levels for the rf modulator.
1746 */
1747bresult boutput_rf_get_audio_volume(
1748                boutput_rf_t rf,
1749                unsigned int *volume      /* [out] current volume of the rf modulater */
1750                )
1751{
1752#ifdef CONFIG_RFM
1753        if (rf->handle == NULL)
1754        {
1755                BDBG_ERR(("%s: RF not already opened!\n", __FUNCTION__));
1756                return berr_invalid_parameter;
1757        }
1758
1759        if (volume == NULL)
1760        {
1761                BDBG_ERR(("%s: pointer to volume is NULL!\n", __FUNCTION__));
1762                return berr_invalid_parameter;
1763        }
1764
1765        *volume = rf->volume;
1766#else
1767        BSTD_UNUSED(rf);
1768        BSTD_UNUSED(volume);
1769#endif
1770        return b_ok;
1771}
1772
1773/*
1774Summary:
1775Open a new decode window.
1776Description:
1777Creates a new decode window on the given display.
1778The window_id is a global id, not relative to the display.
1779
1780On PIP systems, B_ID(1) always refers to PIP.
1781 */
1782bdecode_window_t
1783bdecode_window_open(
1784                bobject_t window_id,    /* window's object id */
1785                bdisplay_t display /* display on which the window appears */
1786                )
1787{
1788        return(bdecode_window_t)window_id;
1789}
1790
1791/*
1792Summary:
1793Hide and close a decode window.
1794Description:
1795Any decode which you started to this decode window should have already been
1796stopped.
1797 */
1798void
1799bdecode_window_close(
1800                bdecode_window_t window
1801                )
1802{
1803}
1804
1805
1806/*
1807Summary:
1808Get the current settings of a decode window.
1809 */
1810bresult
1811bdecode_window_get(
1812                bdecode_window_t window,
1813                bdecode_window_settings *settings         /* [out] */
1814                )
1815{
1816        bobject_t id = (bobject_t)window;
1817        bdisplay_t display = &b_displays[0];
1818        BFMT_VideoInfo formatInfo;
1819        BERR_Code rc;
1820#ifdef CONFIG_NO_SD_OUTPUT
1821        if (id == eBDISPLAY_COMPOSITE)
1822                return BERR_SUCCESS;
1823#endif
1824#if HAS_HMDI   
1825        if (id == eBDISPLAY_HDMI)
1826        {
1827                rc = BFMT_GetVideoFormatInfo(display->hdmiFmt,&formatInfo);
1828                if (rc != BERR_SUCCESS)
1829                {
1830                        BDBG_ERR(("BFMT_GetVideoFormatInfo failed %d\n", rc));
1831                }
1832        }
1833        else
1834#endif
1835        {
1836                rc = BFMT_GetVideoFormatInfo(BFMT_VideoFmt_eNTSC,&formatInfo);
1837                if (rc != BERR_SUCCESS)
1838                {
1839                        BDBG_ERR(("BFMT_GetVideoFormatInfo failed %d\n", rc));
1840                }
1841        }
1842        settings->def_position.x = settings->def_position.y = 0;
1843        settings->def_position.width = formatInfo.ulDigitalWidth;
1844        settings->def_position.height = formatInfo.ulDigitalHeight;
1845        rc = BVDC_Window_GetDstRect(display->disp[id].hVideoWindow, &(settings->position.x), &(settings->position.y), 
1846                        &(settings->position.width), &(settings->position.height));
1847        if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc); return berr_not_supported;}
1848
1849        return b_ok;
1850}
1851
1852/*
1853Summary:
1854Apply new settings to the decode window.
1855Description:
1856Only those individual settings which have changed will be asserted.
1857 */
1858bresult
1859bdecode_window_set(
1860                bdecode_window_t window,
1861                bdecode_window_settings *settings
1862                )
1863{
1864        bobject_t id = (bobject_t)window;
1865        bdisplay_t display = &b_displays[0];
1866        uint32_t scl_x,scl_y,scl_w,scl_h;
1867        BERR_Code rc;
1868
1869#ifdef CONFIG_NO_SD_OUTPUT
1870        if (id == eBDISPLAY_COMPOSITE)
1871                return BERR_SUCCESS;
1872#endif
1873        b_lock_vdc();
1874        rc = BVDC_Window_SetDstRect(display->disp[id].hVideoWindow, settings->position.x, settings->position.y, settings->position.width, settings->position.height);
1875        if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc); return berr_not_supported;}
1876#if 1
1877        rc = BVDC_Window_GetScalerOutput(display->disp[id].hVideoWindow, &scl_x, &scl_y, &scl_w, &scl_h);
1878        if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);return berr_not_supported;}
1879        rc = BVDC_Window_SetScalerOutput(display->disp[id].hVideoWindow, scl_x, scl_y, settings->position.width, settings->position.height);
1880        if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);return berr_not_supported;}
1881#endif
1882        rc = BVDC_ApplyChanges(display->hVdc);
1883        if (rc != BERR_SUCCESS)
1884        {
1885                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
1886        }
1887        b_unlock_vdc();
1888        return b_ok;
1889}
1890
1891/*
1892Summary:
1893Pass new settings to the decode window without BVDC_ApplyChanges.
1894Description:
1895Only those individual settings which have changed will be asserted.
1896 */
1897bresult
1898bdecode_window_preset(
1899                bdecode_window_t window,
1900                bdecode_window_settings *settings
1901                )
1902{
1903        bobject_t id = (bobject_t)window;
1904        bdisplay_t display = &b_displays[0];
1905        uint32_t scl_x,scl_y,scl_w,scl_h;
1906        BERR_Code rc;
1907
1908        b_lock_vdc();
1909        rc = BVDC_Window_SetDstRect(display->disp[id].hVideoWindow, settings->position.x, settings->position.y, settings->position.width, settings->position.height);
1910        if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc); return berr_not_supported;}
1911#if 1
1912        rc = BVDC_Window_GetScalerOutput(display->disp[id].hVideoWindow, &scl_x, &scl_y, &scl_w, &scl_h);
1913        if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);return berr_not_supported;}
1914        rc = BVDC_Window_SetScalerOutput(display->disp[id].hVideoWindow, scl_x, scl_y, settings->position.width, settings->position.height);
1915        if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);return berr_not_supported;}
1916#endif
1917        b_unlock_vdc();
1918        return b_ok;
1919}
1920
1921/**
1922Summary:
1923set HD output options
1924 **/
1925static BERR_Code bdisplay_set_hd_output_options(bdisplay_t display, bdisplay_hd_output_options options)
1926{
1927        BERR_Code rc = BERR_SUCCESS;
1928#if HAS_HDMI
1929        BVDC_AfdSettings afd;
1930
1931        BDBG_MSG(("%s: hd options=%d", __func__, options));
1932        BVDC_Window_GetAfdSettings(display->disp[eBDISPLAY_HDMI].hVideoWindow, &afd);
1933        afd.eClip = BVDC_AfdClip_eOptionalLevel2;
1934        switch (options) {
1935                case bdisplay_hd_output_options_stretch:
1936                        rc = BVDC_Window_SetAspectRatioMode(display->disp[eBDISPLAY_HDMI].hVideoWindow, BVDC_AspectRatioMode_eBypass);
1937                        afd.eMode = BVDC_AfdMode_eDisabled;
1938                        break;
1939
1940                case bdisplay_hd_output_options_pillarbox:
1941                        rc = BVDC_Window_SetAspectRatioMode(display->disp[eBDISPLAY_HDMI].hVideoWindow, BVDC_AspectRatioMode_eUseAllSource);
1942                        afd.eMode = BVDC_AfdMode_eDisabled;
1943                        break;
1944
1945                case bdisplay_hd_output_options_zoom:
1946                        rc = BVDC_Window_SetAspectRatioMode(display->disp[eBDISPLAY_HDMI].hVideoWindow, BVDC_AspectRatioMode_eUseAllDestination);
1947                        afd.eMode = BVDC_AfdMode_eDisabled;
1948                        break;
1949
1950                case bdisplay_hd_output_options_auto:
1951                        rc = BVDC_Window_SetAspectRatioMode(display->disp[eBDISPLAY_HDMI].hVideoWindow, BVDC_AspectRatioMode_eUseAllSource);
1952                        if (BVDC_AfdMode_eDisabled == afd.eMode)
1953                        {
1954                                afd.eMode = BVDC_AfdMode_eStream;
1955                        }
1956                        break; 
1957        }
1958        BVDC_Window_SetAfdSettings(display->disp[eBDISPLAY_HDMI].hVideoWindow, &afd);
1959
1960        rc = BVDC_ApplyChanges(display->hVdc);
1961        if (rc != BERR_SUCCESS)
1962        {
1963                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
1964        }
1965#endif
1966        return rc;
1967}
1968
1969/**
1970Summary:
1971set SD output options
1972 **/
1973static BERR_Code bdisplay_set_sd_output_options(bdisplay_t display, bsettop_display_id_t id, bdisplay_sd_output_options options)
1974{
1975        BERR_Code rc = BERR_SUCCESS;
1976        BVDC_AfdSettings afd;
1977        BFMT_AspectRatio eAspectRatio;
1978        bdisplay_sd_output_options sd_options = options;
1979
1980#ifdef CONFIG_NO_SD_OUTPUT
1981        return BERR_SUCCESS;
1982#endif
1983        BDBG_MSG(("%s: sd options=%d", __func__, options));
1984        BVDC_Window_GetAfdSettings(display->disp[id].hVideoWindow, &afd);
1985        afd.eClip = BVDC_AfdClip_eOptionalLevel2;
1986
1987#if 0
1988        if (eBDISPLAY_COMPOSITE==id)
1989                sd_options = bdisplay_sd_output_options_full;  /* out menu aspect-ratio 4:3 */
1990#endif
1991
1992        /* reset clip first */
1993        BVDC_Window_SetSrcClip(display->disp[id].hVideoWindow, 0, 0, 0, 0);
1994        switch (sd_options) {
1995                case bdisplay_sd_output_options_widescreen: /* out menu aspect-ratio 16:9 */
1996                        //BVDC_Display_SetAspectRatio(display->disp[id].hDisplay, BFMT_AspectRatio_e16_9);
1997                        BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eUseAllSource);
1998                        afd.eMode = BVDC_AfdMode_eDisabled;
1999                        break;
2000
2001                case bdisplay_sd_output_options_full: /* out menu aspect-ratio 4:3 */
2002                        //BVDC_Display_SetAspectRatio(display->disp[id].hDisplay, BFMT_AspectRatio_e4_3);
2003#if SUPPORT_DST_PLATFORM
2004                        BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eBypass);
2005#else                   
2006                        BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eUseAllDestination);
2007#endif
2008                        afd.eMode = BVDC_AfdMode_eDisabled;
2009                        break;
2010
2011                case bdisplay_sd_output_options_auto: /* out menu aspect-ratio auto */
2012#if 0
2013                        if (display->hdmiFmt == BFMT_VideoFmt_eNTSC)
2014                                eAspectRatio = display->auto_hdmi_480i_aspect_ratio;
2015                        else if (display->hdmiFmt == BFMT_VideoFmt_e480p)
2016                                eAspectRatio = display->auto_hdmi_480p_aspect_ratio;
2017                        else
2018                                eAspectRatio = BFMT_AspectRatio_e16_9;
2019                        BVDC_Display_SetAspectRatio(display->disp[id].hDisplay, eAspectRatio);
2020                        if (eAspectRatio == BFMT_AspectRatio_e16_9)
2021                                BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eUseAllSource);
2022                        else
2023                                BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eUseAllDestination);
2024#endif
2025                        BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eUseAllDestination);
2026                        if (BVDC_AfdMode_eDisabled == afd.eMode)
2027                        {
2028                                afd.eMode = BVDC_AfdMode_eStream;
2029                        }
2030                        break;
2031
2032                case bdisplay_sd_output_options_zoom: /* just clip the source window to show zoom effect */
2033                        /* do we need video source format as indicator for clip parameters? */
2034#if SUPPORT_DST_PLATFORM
2035                        BVDC_Window_SetAspectRatioMode(display->disp[id].hVideoWindow, BVDC_AspectRatioMode_eBypass);
2036#endif
2037                        BVDC_Window_SetSrcClip(display->disp[id].hVideoWindow, 40, 40, 30, 30);
2038                        break; 
2039        }
2040        BVDC_Window_SetAfdSettings(display->disp[id].hVideoWindow, &afd);
2041
2042        rc = BVDC_ApplyChanges(display->hVdc);
2043        if (rc != BERR_SUCCESS)
2044        {
2045                BDBG_ERR(("BVDC_ApplyChanges failed %d\n", rc));
2046        }
2047        return rc;
2048}
2049
2050
2051/**
2052Summary:
2053set hdmi output options
2054 **/
2055static BERR_Code bdisplay_set_hdmi_output_options(bdisplay_t display)
2056{
2057#if HAS_HDMI
2058#ifndef HDMI_SD_WIDE_SCREEN
2059        if ((display->hdmiFmt == BFMT_VideoFmt_e480p) || (display->hdmiFmt == BFMT_VideoFmt_eNTSC))
2060        {
2061                return bdisplay_set_sd_output_options(display, eBDISPLAY_HDMI, display->settings.hd_options);
2062        }
2063        else
2064#endif
2065        {
2066                return bdisplay_set_hd_output_options(display, display->settings.hd_options);
2067        }
2068#else
2069        return 0;
2070#endif
2071
2072}
2073
2074/* ------------   vbi  ----------------------------- */
2075
2076bresult bdisplay_enable_vbi(bool enable)
2077{
2078        BERR_Code rc = BERR_SUCCESS;
2079
2080        bdisplay_t display = &b_displays[0];
2081        rc = BVBI_Encode_SetCC(display->vbi.enc_core, enable);
2082        if (rc != BERR_SUCCESS) {
2083                BDBG_ERR(("Error to VBI encoder CC mode"));
2084                return rc;
2085        }
2086        rc = BVBI_Encode_ApplyChanges(display->vbi.enc_core);
2087        if (rc != BERR_SUCCESS) {
2088                BDBG_ERR(("Fail to apply VBI encoder settings."));
2089        }
2090        return rc;
2091}
2092
2093#ifdef  HAS_VBI
2094#define VBI_BOTTOM_LIST_OFFSET          263
2095#define VBI_TOP_LINE_BASE                       10
2096
2097static BERR_Code vbi_P_SetGemstarOptions(BVBI_Encode_Handle hVbiEnc)
2098{
2099#if (BVBI_P_GEMSTAR_OPTIONS_STRUCT)
2100        BVBI_GSOptions gsOptions = { false, VBI_TOP_LINE_BASE, 0x03e0, VBI_BOTTOM_LIST_OFFSET + VBI_TOP_LINE_BASE, 0x03e0 };
2101        return BVBI_Encode_SetGemstarOptions (hVbiEnc, &gsOptions);
2102#else
2103        /* NEED to save values to use later */ 
2104        return BVBI_Encode_SetGemstarOptions (hVbiEnc, VBI_TOP_LINE_BASE, 0x007C, 274, 0x007C);
2105#endif
2106}
2107
2108/*
2109Summary:
2110enable amol and gs
2111Description:
2112enable/disable amol and gs
2113 */
2114bresult bdisplay_vbi_enable_amol_gs(bool enable)
2115{
2116        BERR_Code rc = BERR_SUCCESS;
2117
2118        bdisplay_t display = &b_displays[0];
2119
2120        /* if called before bdisplay_p_vbi_connect */
2121        if (!display->vbi.enc_core)
2122                return BERR_NOT_INITIALIZED;
2123
2124        rc = BVBI_Encode_SetGemstar(display->vbi.enc_core, enable);
2125        if (rc != BERR_SUCCESS) {
2126                BDBG_ERR(("%s: BVBI_Encode_SetGemstar failed",__func__));
2127                return rc;
2128        }
2129        vbi_P_SetGemstarOptions(display->vbi.enc_core); 
2130
2131        rc = BVBI_Encode_SetAMOL(display->vbi.enc_core, enable);
2132        if (rc != BERR_SUCCESS) {
2133                BDBG_ERR(("%s: BVBI_Encode_GetAMOL failed",__func__));
2134                return rc;
2135        }
2136        rc = BVBI_Encode_ApplyChanges(display->vbi.enc_core);
2137        return rc;
2138}
2139
2140bresult vbi_scte127_write_isr(pscte_127_handle pscte_127, int field_parity)
2141{
2142        BVBI_Field_Handle field = NULL;
2143        BERR_Code rc = BERR_SUCCESS;
2144        bdisplay_t display = &b_displays[0];
2145        static BVBI_GSData      gs_data[2];
2146        unsigned int i, gs_ret, amol_ret;
2147        int gs_count, line_offset;
2148        bool obtained = false;
2149        int type = 0;           /* AMOL TYPE */
2150        unsigned char amol_data[24];
2151
2152        /* try to reuse pending filed if any */
2153        rc = BVBIlib_Encode_GetOldestDatum_isr(display->vbi.enc, &field);
2154        if (!rc) {
2155                /* need to chcek field pointer since the function doesn't clear it even if no field available */
2156                if (field) {
2157                        if (field->ulWhichPresent & BVBI_P_SELECT_GS) {
2158                                BDBG_WRN(("%s: GS data existed already", __func__));
2159                                /* note that we have to make sure to get GS data per field so that buffer is not overflow */
2160                                /* currently will reset scte 127 buffers if overflow */
2161                                return -1;
2162                        }
2163                        if (field->ulWhichPresent & BVBI_P_SELECT_AMOL) {
2164                                BDBG_WRN(("%s: AMOL data existed already", __func__));
2165                                /* note that we have to make sure to get AMOL data per field so that buffer is not overflow */
2166                                return -1;
2167                        }
2168                        /* need to make sure polarity matches */
2169                        BVBI_Field_GetPolarity_isr(field, &i);
2170                        if (i != (1 << field_parity)) {
2171                                BDBG_MSG(("%s: wrong polarity, what to do?", __func__));
2172                                //return -1;
2173                                field_parity = !field_parity;
2174                        }
2175                }
2176        }
2177
2178        gs_ret = scte_127_get_gs_data_buf_isr(pscte_127, field_parity, &line_offset, &gs_count, (uint32_t *)&gs_data[field_parity].ulData);
2179        amol_ret = scte_127_get_amol_data_buf_isr_ex(pscte_127, field_parity, &type, amol_data);
2180        if (gs_ret || amol_ret) {
2181                if (!field) {
2182                        obtained = true;
2183                        rc = BVBIlib_List_Obtain_isr(display->vbi.hVbilist, &field);
2184                        if (rc) {
2185                                goto done_write;
2186                        }       
2187                        /* if we can't get one, just let the data stay pending.
2188                           we still need to fall through and allow VBIlib to empty its queue. */
2189                        (void)BVBI_Field_SetPolarity_isr(field, (1 << field_parity));
2190                }
2191
2192                if (gs_ret && gs_count) {
2193                        /* put the data to GSData structure */
2194                        gs_data[field_parity].ulDataLines = 0;
2195                        gs_data[field_parity].ulErrorLines = 0;
2196                        for (i = 0; i < BAVC_VBI_GS_MAX_LINES; i++) {
2197                                if (i < gs_count) {
2198                                        gs_data[field_parity].ulDataLines |= (1L << (line_offset + i));
2199                                }
2200                                else {
2201                                        gs_data[field_parity].ulData[i] = 0;
2202                                }
2203                        }
2204
2205#if HAS_VBI
2206                        scte_127_set_gs_line_mask(pscte_127, field_parity, VBI_TOP_LINE_BASE, (gs_data[field_parity].ulDataLines >> VBI_TOP_LINE_BASE));
2207#endif
2208
2209                        rc = BVBI_Field_SetGSData_isr(field, &gs_data[field_parity]);
2210                        if (rc!=BERR_SUCCESS) {
2211                                BDBG_WRN(("%s: BVBI_Field_SetGSData_isr failed", __func__));
2212                                //goto done_write;
2213                        }
2214                }
2215
2216                /* should we send NULL data as well? */
2217                if (amol_ret && type) {
2218                        //TODO check amol module to see if it also check line mask or not */   
2219                        /* put the data to GSData structure */
2220                        rc = BVBI_Field_SetAMOLData_isr(field, type, amol_data,40 /* JPF Liqun to identify correct way to obtain amol length */);
2221                        if (rc!=BERR_SUCCESS) {goto done_write;}
2222                }
2223
2224                if (obtained) {
2225                        /* This actually sends it to the VEC and consumes the field */
2226                        if ((rc = BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field))) {
2227                                /* if it fails, assume it's a queue overflow and we're done */
2228                                BDBG_WRN(("%s: VBI encoder queue overflow", __func__));
2229                                /* if we can't enqueue, the buffer is probably full. Try to recover by flushing. */
2230                                BVBIlib_List_Return_isr(display->vbi.hVbilist, field);
2231                                //BVBIlib_Encode_Flush_isr(display->vbi.enc);
2232                        }
2233                        field = NULL;
2234                }
2235
2236done_write:
2237                if (BERR_SUCCESS != rc) {
2238                        BDBG_WRN(("%s: failed (rc=0x%x)", __func__, rc));
2239                }
2240                if (field && obtained) {
2241                        BVBIlib_List_Return_isr(display->vbi.hVbilist, field);
2242                }
2243        }
2244        return rc;
2245}
2246
2247#if 0
2248bresult vbi_gs_write_isr(pscte_127_handle pscte_127, int field_parity)
2249{
2250        BVBI_Field_Handle field = NULL;
2251        BERR_Code rc = BERR_SUCCESS;
2252        bdisplay_t display = &b_displays[0];
2253        static BVBI_GSData      gs_data[2];
2254        unsigned int i;
2255        int gs_count, line_offset;
2256        bool obtained = false;
2257
2258        /* try to reuse pending filed if any */
2259        rc = BVBIlib_Encode_GetOldestDatum_isr(display->vbi.enc, &field);
2260        if (!rc) {
2261                /* need to chcek field pointer since the function doesn't clear it even if no field available */
2262                if (field) {
2263                        if (field->ulWhichPresent & BVBI_P_SELECT_GS) {
2264                                BDBG_WRN(("%s: GS data existed already", __func__));
2265                                /* not that we have to make sure to get GS data per field so that buffer is not overflow */
2266                                /* so just overwrite gs data if VBI encoder is not fast enough */
2267                                return -1;
2268                        }
2269                        /* need to make sure polarity matches */
2270                        BVBI_Field_GetPolarity_isr(field, &i);
2271                        if (i != (1 << field_parity)) {
2272                                BDBG_MSG(("%s: wrong polarity, what to do?", __func__));
2273                                //return -1;
2274                                field_parity = !field_parity;
2275                        }
2276                }
2277        }
2278
2279        if (scte_127_get_gs_data_buf_isr(pscte_127, field_parity, &line_offset, &gs_count, (uint32_t *)&gs_data[field_parity].ulData)) {
2280                if (!field) {
2281                        obtained = true;
2282                        rc = BVBIlib_List_Obtain_isr(display->vbi.hVbilist, &field);
2283                        if (rc) {
2284                                goto done_write;
2285                        }       
2286                        /* if we can't get one, just let the data stay pending.
2287                           we still need to fall through and allow VBIlib to empty its queue. */
2288                        (void)BVBI_Field_SetPolarity_isr(field, (1 << field_parity));
2289                }
2290
2291                /* put the data to GSData structure */
2292                gs_data[field_parity].ulDataLines = 0;
2293                gs_data[field_parity].ulErrorLines = 0;
2294                for (i = 0; i < BAVC_VBI_GS_MAX_LINES; i++) {
2295                        if (i < gs_count) {
2296                                gs_data[field_parity].ulDataLines |= (1L << (line_offset + i));
2297                        }
2298                        else {
2299                                gs_data[field_parity].ulData[i] = 0;
2300                        }
2301                }
2302
2303#if HAS_VBI
2304                scte_127_set_gs_line_mask(pscte_127, field_parity, VBI_TOP_LINE_BASE, (gs_data[field_parity].ulDataLines >> VBI_TOP_LINE_BASE));
2305#endif
2306
2307                rc = BVBI_Field_SetGSData_isr(field, &gs_data[field_parity]);
2308                if (rc!=BERR_SUCCESS) {goto done_write;}
2309
2310                if (obtained) {
2311                        /* This actually sends it to the VEC and consumes the field */
2312                        if ((rc = BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field))) {
2313                                /* if it fails, assume it's a queue overflow and we're done */
2314                                BDBG_WRN(("%s: VBI encoder queue overflow", __func__));
2315                                /* if we can't enqueue, the buffer is probably full. Try to recover by flushing. */
2316                                BVBIlib_List_Return_isr(display->vbi.hVbilist, field);
2317                                //BVBIlib_Encode_Flush_isr(display->vbi.enc);
2318                        }
2319                        field = NULL;
2320                }
2321
2322done_write:
2323                if (BERR_SUCCESS != rc) {
2324                        BDBG_WRN(("%s: failed (rc=0x%x)", __func__, rc));
2325                }
2326                if (field && obtained) {
2327                        BVBIlib_List_Return_isr(display->vbi.hVbilist, field);
2328                }
2329        }
2330        return rc;
2331}
2332
2333bresult vbi_amol_write_isr(pscte_127_handle pscte_127, int field_parity)
2334{
2335        BVBI_Field_Handle field = NULL;
2336        BERR_Code rc = BERR_SUCCESS;
2337        bdisplay_t display = &b_displays[0];
2338        pscte_127_data  pdata;
2339        bool full = false;
2340
2341        if (NULL == pscte_127)
2342                return BERR_NOT_INITIALIZED;
2343
2344        /* not that currently AMOL module doens't take line offset, but it may need later */
2345        /* TODO:: reordering may be required for some streams..*/
2346        /* Set up the field. If we fail, make sure to exit the critical section
2347           and free memory */
2348        while ((pdata = scte_127_get_amol_data_buf_isr(pscte_127, field_parity))) {
2349                /* get a field */
2350                rc = BVBIlib_List_Obtain_isr(display->vbi.hVbilist, &field);
2351                if (rc!=BERR_SUCCESS) {goto done_write;} /* running out of fields is normal flow control */
2352
2353                rc = BVBI_Field_SetPolarity_isr(field, (1 << pdata->field_parity));
2354
2355                /* put the data to GSData structure */
2356                rc = BVBI_Field_SetAMOLData_isr(field, pdata->amol_type, pdata->u.amol96);
2357                if (rc!=BERR_SUCCESS) {goto done_write;}
2358
2359                /* This actually sends it to the VEC and consumes the field */
2360                if (BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field)) {
2361                        /* if it fails, assume it's a queue overflow and we're done */
2362                        BDBG_MSG(("%s: VBI encoder queue overflow", __func__));
2363                        /* if we can't enqueue, the buffer is probably full. Try to recover by flushing. */
2364                        BVBIlib_Encode_Flush_isr(display->vbi.enc);
2365                        full = true;
2366                }
2367                else {
2368                        field = NULL;
2369                }
2370
2371done_write:
2372                if (pdata) {
2373                        scte_127_queue_buffer_isr(pscte_127, pdata);
2374                        pdata = NULL;
2375                }
2376                if (BERR_SUCCESS != rc) {
2377                        BDBG_WRN(("%s: failed (rc=0x%x)", __func__, rc));
2378                }
2379                if (field) {
2380                        BVBIlib_List_Return_isr(display->vbi.hVbilist, field);
2381                }
2382
2383                if (full || rc)
2384                        break;
2385
2386                field = NULL; /* consumed */
2387        }
2388        return rc;
2389}
2390#endif
2391#endif
2392
2393bresult vbi_cc_write_isr(const unsigned char* ccData, size_t length)
2394{
2395        BVBI_Field_Handle field = NULL;
2396        BERR_Code rc = BERR_SUCCESS;
2397        unsigned int i;
2398        int full = 0;
2399        bdisplay_t display = &b_displays[0];
2400
2401        /* TODO:: reordering may be required for some streams..*/
2402
2403        for (i=0; i<length; i++) {
2404                /* Set up the field. If we fail, make sure to exit the critical section
2405                   and free memory */
2406
2407                rc = BVBIlib_List_Obtain_isr(display->vbi.hVbilist, &field);
2408                if (rc!=BERR_SUCCESS) {goto done_write;} /* running out of fields is normal flow control */
2409
2410                rc = BVBI_Field_SetCCData_isr(field, ccData[3*i+1], ccData[3*i+2]);
2411                if (rc!=BERR_SUCCESS) {goto done_write;}
2412
2413                rc = BVBI_Field_SetPolarity_isr(field, 1<<(ccData[3*i]?1:0));
2414                if (rc!=BERR_SUCCESS) {goto done_write;}
2415                /* This actually sends it to the VEC and consumes the field */
2416                if (BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field)) {
2417                        /* if it fails, assume it's a queue overflow and we're done */
2418                        BDBG_MSG(("VBI encoder queue overflow"));
2419                        full = 1;
2420                        /* if we can't enqueue, the buffer is probably full. Try to recover by flushing. */
2421                        BVBIlib_Encode_Flush_isr(display->vbi.enc);
2422                }
2423                else {
2424                        field = NULL;
2425                }
2426done_write:
2427                if (field) {
2428                        BVBIlib_List_Return_isr(display->vbi.hVbilist, field);
2429                }
2430
2431                if (full || rc)
2432                        break;
2433
2434                field = NULL; /* consumed */
2435        }
2436        return rc;     
2437}
2438
2439bresult bdisplay_vbi_clear_cc(void)
2440{
2441        unsigned char ccData[18];
2442        int i;
2443
2444        /* Force send EDM command to clear */
2445        for (i=0; i<2; i++) {
2446                ccData[i*3] = 0;
2447                ccData[i*3+1] = 0x14;
2448                ccData[i*3+2] = 0x2c;
2449        }
2450
2451        /* Force send ENM command to clear */
2452        for (i=2; i<4; i++) {
2453                ccData[i*3] = 0;
2454                ccData[i*3+1] = 0x14;
2455                ccData[i*3+2] = 0x2e;
2456        }
2457
2458        /* EOC command */
2459        for (i=4; i<6; i++) {
2460                ccData[i*3] = 0;
2461                ccData[i*3+1] = 0x14;
2462                ccData[i*3+2] = 0x2f;
2463        }
2464
2465        BKNI_EnterCriticalSection();
2466        vbi_cc_write_isr((const unsigned char *)ccData, 6);
2467        BKNI_LeaveCriticalSection();
2468
2469        return BERR_SUCCESS;
2470}
2471
2472static bresult bdisplay_p_vbi_open(bdisplay_t display)
2473{
2474        BERR_Code rc;
2475        BVBIlib_List_Settings vbilistsettings;
2476        int queue_size;
2477
2478        rc = BVBI_Open(&display->vbi.hVbi, GetCHP(), GetREG(), GetHEAP(), NULL);
2479        if (rc != BERR_SUCCESS) { return rc; }
2480
2481        rc = BVBIlib_Open(&display->vbi.hVbilib, display->vbi.hVbi);
2482        if (rc != BERR_SUCCESS) { return rc; }
2483
2484        BVBIlib_List_GetDefaultSettings(&vbilistsettings);
2485
2486        queue_size = 17 * 2;
2487#if HAS_VBI
2488        vbilistsettings.bAllowGemstar   = true;
2489        vbilistsettings.bAllowAmol              = true;
2490#endif
2491        rc = BVBIlib_List_Create(&display->vbi.hVbilist, display->vbi.hVbi,
2492                        queue_size/* number of entries. This should be one greater than the number
2493                                                 passed to BVBIlib_Encode_Create because of vbilib internal
2494                                                 resource management. */,
2495                        &vbilistsettings);
2496        //BVBIlib_DCCReorder_Open(&display->vbi.hReorder, 16, 15);
2497
2498#if HAS_VBI
2499        bdisplay_vbi_enable_amol_gs(false);
2500#endif
2501
2502        return rc;
2503}
2504
2505static bresult bdisplay_p_vbi_close(bdisplay_t display)
2506{
2507        if (display->vbi.hVbilist) 
2508                BVBIlib_List_Destroy(display->vbi.hVbilist);
2509        if (display->vbi.hVbilib)
2510                BVBIlib_Close(display->vbi.hVbilib);
2511        if (display->vbi.hVbi)
2512                BVBI_Close(display->vbi.hVbi);
2513        return BERR_SUCCESS;
2514}
2515
2516static void bdisplay_p_vbi_isr(void *parm1, int parm2)
2517{
2518        bdisplay_t display = (bdisplay_t)parm1;
2519        BERR_Code rc;
2520        BAVC_Polarity polarity = (BAVC_Polarity)parm2;
2521#ifdef HAS_VBI
2522        pscte_127_handle    pscte_127;
2523
2524        pscte_127 = scte_127_get_handle();
2525        if (pscte_127) {
2526                if (scte_127_has_data(pscte_127, polarity)) {
2527                        //vbi_amol_write_isr(pscte_127, polarity);
2528                        //vbi_gs_write_isr(pscte_127, polarity);
2529                        vbi_scte127_write_isr(pscte_127, polarity);
2530                }
2531        }
2532#endif
2533
2534        rc = BVBIlib_Encode_Data_isr(display->vbi.enc, polarity);
2535        if (rc!=BERR_SUCCESS) {
2536                BDBG_ERR(("BVBIlib_Encode_Data_isr returned error %x, ignored", rc));
2537        }
2538        return;
2539}
2540
2541static bresult bdisplay_p_vbi_connect(bdisplay_t display)
2542{
2543        BAVC_VbiPath vbi_path;
2544        BERR_Code rc;
2545        BINT_Id tf_isr, bf_isr;
2546        int queue;
2547
2548        BDBG_MSG(("connect display %p to vbi", display));
2549
2550        /* connect vbi encoder to the composite display output */
2551        rc = BVDC_Display_GetVbiPath(display->disp[eBDISPLAY_COMPOSITE].hDisplay, &vbi_path);
2552        if (rc!=BERR_SUCCESS) {
2553                BDBG_ERR(("Couldn't get the VBI path for composite display output : %x", rc));
2554                return rc;
2555        }
2556
2557        switch (vbi_path) {
2558#if defined(BCHP_INT_ID_VBI_0_0_INTR)
2559                case BAVC_VbiPath_eVec0:
2560                        tf_isr = BCHP_INT_ID_VBI_0_0_INTR;
2561                        bf_isr = BCHP_INT_ID_VBI_0_1_INTR;
2562                        break;
2563#if defined BCHP_INT_ID_VBI_1_0_INTR && defined BCHP_INT_ID_VBI_1_1_INTR
2564                case BAVC_VbiPath_eVec1:
2565                        tf_isr = BCHP_INT_ID_VBI_1_0_INTR;
2566                        bf_isr = BCHP_INT_ID_VBI_1_1_INTR;
2567                        break;
2568#endif
2569#if defined(BCHP_INT_ID_ANCIL_VBI_0_INTR)
2570                case BAVC_VbiPath_eBypass0:
2571                        tf_isr = BCHP_INT_ID_ANCIL_VBI_0_INTR;
2572                        bf_isr = BCHP_INT_ID_ANCIL_VBI_1_INTR;
2573                        break;
2574#endif
2575#if defined(BCHP_INT_ID_VBI_2_0_INTR)
2576                case BAVC_VbiPath_eVec2:
2577                        tf_isr = BCHP_INT_ID_VBI_2_0_INTR;
2578                        bf_isr = BCHP_INT_ID_VBI_2_1_INTR;
2579                        break;
2580#endif
2581#else
2582                case BAVC_VbiPath_eVec0:
2583                        tf_isr = BCHP_INT_ID_PRIM_VBI_0_INTR;
2584                        bf_isr = BCHP_INT_ID_PRIM_VBI_1_INTR;
2585                        break;
2586#if defined BCHP_INT_ID_SEC_VBI_0_INTR && defined BCHP_INT_ID_SEC_VBI_1_INTR
2587                case BAVC_VbiPath_eVec1:
2588                        tf_isr = BCHP_INT_ID_SEC_VBI_0_INTR;
2589                        bf_isr = BCHP_INT_ID_SEC_VBI_1_INTR;
2590                        break;
2591#endif
2592#if defined(BCHP_INT_ID_BYPASS_VBI_0_INTR)
2593                case BAVC_VbiPath_eBypass0:
2594                        tf_isr = BCHP_INT_ID_BYPASS_VBI_0_INTR;
2595                        bf_isr = BCHP_INT_ID_BYPASS_VBI_1_INTR;
2596                        break;
2597#endif
2598#if defined(BCHP_INT_ID_TERT_VBI_0_INTR)
2599                case BAVC_VbiPath_eVec2:
2600                        tf_isr = BCHP_INT_ID_TERT_VBI_0_INTR;
2601                        bf_isr = BCHP_INT_ID_TERT_VBI_1_INTR;
2602                        break;
2603#endif
2604#endif
2605                default:
2606                        rc = BERR_TRACE(BERR_NOT_SUPPORTED);
2607                        goto err_vbi_path;
2608        }
2609
2610        /* unfortunately we have to recreate everything because the vbi_path might change */
2611        rc = BVBI_Encode_Create(display->vbi.hVbi, vbi_path, &display->vbi.enc_core);
2612        if (rc!=BERR_SUCCESS) {goto err_vbi_encode;}
2613
2614        queue = 32;
2615
2616        rc = BVBIlib_Encode_Create(display->vbi.hVbilib, display->vbi.hVbilist, display->vbi.enc_core,
2617                        queue /* queue size. this was 4 for analog, but must be increase for MVD USERDATA */,
2618                        &display->vbi.enc);
2619        if (rc!=BERR_SUCCESS) {goto err_vbilib_encode;}
2620
2621        /* we are using top ISR to feed bottom field data and bottom field isr to feed top field data */
2622        rc = BINT_CreateCallback(&display->vbi.tf_isr, GetINT(), tf_isr, bdisplay_p_vbi_isr, display, BAVC_Polarity_eBotField);
2623        if (rc!=BERR_SUCCESS) {goto err_tf_isr;}
2624
2625        rc = BINT_CreateCallback(&display->vbi.bf_isr, GetINT(), bf_isr, bdisplay_p_vbi_isr, display, BAVC_Polarity_eTopField);
2626        if (rc!=BERR_SUCCESS) {goto err_bf_isr;}
2627
2628        rc = BINT_EnableCallback(display->vbi.tf_isr);
2629        if (rc!=BERR_SUCCESS) {goto err_isr_cfg;}
2630
2631        rc = BINT_EnableCallback(display->vbi.bf_isr);
2632        if (rc!=BERR_SUCCESS) {goto err_isr_cfg;}
2633
2634        BVBI_Encode_SetVideoFormat(display->vbi.enc_core, BFMT_VideoFmt_eNTSC);
2635
2636        rc = BVBI_Encode_SetCC(display->vbi.enc_core, true);
2637        if (rc!=BERR_SUCCESS) {goto err_enable_vbi;}
2638
2639#ifdef  HAS_VBI
2640        rc = BVBI_Encode_SetGemstar(display->vbi.enc_core, true);
2641        if (rc!=BERR_SUCCESS) {goto err_enable_vbi;}
2642
2643        rc = BVBI_Encode_SetAMOL(display->vbi.enc_core, true);
2644        if (rc!=BERR_SUCCESS) {goto err_enable_vbi;}
2645#endif
2646        rc = BVBI_Encode_ApplyChanges(display->vbi.enc_core);
2647        if (rc!=BERR_SUCCESS) {goto err_enable_vbi;}
2648
2649        return rc;
2650
2651err_enable_vbi:
2652err_isr_cfg:
2653        BINT_DestroyCallback(display->vbi.bf_isr);
2654err_bf_isr:
2655        BINT_DestroyCallback(display->vbi.tf_isr);
2656err_tf_isr:
2657        BVBIlib_Encode_Destroy(display->vbi.enc);
2658err_vbilib_encode:
2659        BVBI_Encode_Destroy(display->vbi.enc_core);
2660        display->vbi.enc_core = NULL;
2661err_vbi_encode:
2662err_vbi_path:
2663        return rc;
2664}
2665
2666static bresult bdisplay_p_vbi_disconnect(bdisplay_t display)
2667{
2668#ifdef  HAS_VBI
2669        BVBI_Encode_SetGemstar(display->vbi.enc_core, false);
2670        BVBI_Encode_GetAMOL(display->vbi.enc_core, false);
2671#endif
2672
2673        bdisplay_enable_vbi(false);
2674        if (display->vbi.bf_isr) 
2675                BINT_DestroyCallback(display->vbi.bf_isr);
2676        if (display->vbi.tf_isr)
2677                BINT_DestroyCallback(display->vbi.tf_isr);
2678        if (display->vbi.enc)
2679                BVBIlib_Encode_Destroy(display->vbi.enc);
2680        if (display->vbi.enc_core)
2681                BVBI_Encode_Destroy(display->vbi.enc_core);
2682        display->vbi.enc_core = NULL;
2683        return BERR_SUCCESS;
2684}
2685
2686bresult bdisplay_set_vbi_rating_info(
2687                bdisplay_t display, unsigned int ratings_tv, unsigned int ratings_movie,
2688                unsigned int content_v, unsigned int content_s, unsigned int content_l, unsigned int content_d)
2689{
2690        unsigned char xds_data[9];
2691
2692        xds_data[0] = xds_data[3] = xds_data[6] = 1;
2693        xds_data[1] = 0x1;
2694        xds_data[2] = 0x05;
2695
2696        /* character 1 : x 1 D/a2 a1    a0   r2 r1 r0
2697         * character 2 : x 1 (F)V S     L/a3 g2 g1 g0 */
2698        xds_data[4] = ratings_movie|0x40;
2699        xds_data[4] |= 0x08;
2700        xds_data[4] |= (content_d << 5);
2701
2702        xds_data[5] = ratings_tv | 0x40;
2703        xds_data[5] |= (content_l<<3);
2704        xds_data[5] |= (content_s<<4);
2705        xds_data[5] |= (content_v<<5);
2706
2707        xds_data[7] = 0x0f;
2708        xds_data[8] = 0x1d;             
2709
2710        BKNI_EnterCriticalSection();
2711        vbi_cc_write_isr(xds_data,3);
2712        BKNI_LeaveCriticalSection();
2713        return BERR_SUCCESS;
2714}
2715
2716bresult bdisplay_output_rf_enable(
2717                bdisplay_t display,     /* handle returned by bdisplay_open */
2718                bool enable             
2719                )
2720{
2721        bresult res = b_ok;
2722
2723        b_lock_vdc();
2724#ifdef CONFIG_RFM
2725        bdisplay_settings settings;
2726
2727        bdisplay_get(display, &settings);
2728        if (settings->rf) {
2729                settings->rf->update = true;
2730                settings->rf->enable_output = enable;
2731                res = boutput_p_rf_set(settings->rf, &settings->rf->cfg);
2732                /* volume to 0 ? */
2733        }
2734#else
2735        /* simply to set window invisible? */
2736        res = BVDC_Window_SetVisibility(display->disp[eBDISPLAY_COMPOSITE].hVideoWindow, enable);
2737        res = BVDC_ApplyChanges(display->hVdc);
2738#endif
2739        b_unlock_vdc();
2740        return res;     
2741}
2742
2743/*
2744Summary:
2745enable visibility of HDMI window
2746Description:
2747enable/disable HDMI window in case HDCP authentication failed
2748 */
2749bresult bdisplay_output_hdmi_enable(
2750                bdisplay_t display, /* handle returned by bdisplay_open */
2751                bool enable
2752                )
2753{
2754        bresult res = b_ok;
2755
2756#if HAS_HDMI
2757        if (!display->disp[eBDISPLAY_HDMI].hVideoWindow)
2758                return res;
2759        b_lock_vdc();
2760        /* simply to set window invisible? */
2761        res = BVDC_Window_SetVisibility(display->disp[eBDISPLAY_HDMI].hVideoWindow, enable);
2762        res = BVDC_ApplyChanges(display->hVdc);
2763        b_unlock_vdc();
2764#endif
2765        return res;
2766}
2767
2768
2769/*
2770Summary:
2771        return default display settings
2772Description:
2773        return default display settings
2774*/
2775void bdisplay_get_default_settings(bdisplay_settings *psettings)
2776{
2777        if (psettings) {
2778                BKNI_Memcpy(psettings, &b_displays[0].settings, sizeof(bdisplay_settings));
2779        }
2780}
2781
2782/*
2783 * Summary:
2784 * power management for VDC block
2785 */
2786void bdisplay_standby(bdisplay_t display, bool standby)
2787{
2788        if (standby) {
2789                BVDC_Standby(display->hVdc, NULL);
2790        }
2791        else {
2792                BVDC_Resume(display->hVdc);
2793        }
2794}
2795
Note: See TracBrowser for help on using the repository browser.