source: svn/newcon3bcm2_21bu/BSEAV/api/src/nexus/bsettop_display.c @ 22

Last change on this file since 22 was 22, checked in by phkim, 11 years ago
  1. phkim
  2. newcon3sk 를 kctv 로 브랜치 함
  • Property svn:executable set to *
File size: 124.2 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2010, 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: bsettop_display.c $
11 * $brcm_Revision: 177 $
12 * $brcm_Date: 8/3/10 5:12p $
13 * $brcm_Revision: 177 $
14 * $brcm_Date: 8/3/10 5:12p $
15 *
16 * Module Description:
17 *
18 * Revision History:
19 *
20 * $brcm_Log: /BSEAV/api/src/nexus/bsettop_display.c $
21 *
22 * 177   8/3/10 5:12p spothana
23 * SW7420-732: Use application defined Off DNR/ANR value and VDC ANR/DNR
24 * enable flag to determine on and off state.
25 *
26 * 176   7/20/10 5:27p spothana
27 * SW7420-732: The lowest level in DNR and ANR levels should not be zero.
28 * Using the max -ve as a level for turning off ANR and DNR blocks.
29 *
30 * 175   7/20/10 2:57p spothana
31 * SW7420-732: 7208 build fix.
32 *
33 * 174   7/19/10 7:24p spothana
34 * SW7420-732: Fixing the flashes made ANR/DNR settings ineffective. In
35 * get window settings, get the ANR/DNR levels
36 *
37 * 173   7/15/10 5:19p spothana
38 * SW7420-732: Correcting the ANR setting condition.
39 *
40 * 172   7/15/10 4:52p spothana
41 * SW7420-732: All display outputs flashing when picture quality controls
42 * are modified in the Brutus GUI. Don't apply DNR and ANR settings if
43 * they have not changed.
44 *
45 * 171   6/11/10 2:23p gskerl
46 * SW7468-254: Fixed segfault when Brutus exits without DVI or HDMI device
47 * attached
48 *
49 * 170   6/8/10 6:52p mward
50 * SW7400-2793: When moving MAD from one window to another, must update to
51 * apply the changes after removing it from the first, so that the
52 * resource will be available when adding it to the second.
53 *
54 * 169   5/14/10 12:29p jtna
55 * SW7125-277: Coverity Defect ID:21062 STACK_USE
56 *
57 * 168   4/15/10 11:15a jtna
58 * SW7125-277: fix brackets
59 *
60 * 167   4/14/10 11:20a calvinho
61 * SW7125-276: Fix Coverity Defect ID:21017 FORWARD_NULL bsettop_display.c
62 *
63 * 166   4/12/10 11:38a calvinho
64 * SW7125-277: Fix Coverity flags 21062 and 20422
65 *
66 * 165   3/29/10 2:19p erickson
67 * SW7405-2724: don't switch MAD off for playback pause. use GameMode
68 * instead. this prevents the black flash due to BVN reconfig.
69 *
70 * 164   3/19/10 5:59p jgarrett
71 * SW7405-4040: Ensuring audio and video are on the same timebase
72 *
73 * 163   3/3/10 3:02p nickh
74 * SW7420-565: Refactor dynamic contrast settings
75 *
76 * 162   2/12/10 3:41p nickh
77 * SW7420-309: Add deringing and dejagging support in the shim layer for
78 * split screen demo mode
79 *
80 * 161   2/3/10 10:48a jgarrett
81 * SW7405-3858: Handling recursive audio display disable calls
82 *
83 * 160   1/28/10 11:43a gmohile
84 * SW7405-3635 : Fix compile error for non-rfm platforms
85 *
86 * 159   1/26/10 6:02p jgarrett
87 * SW7405-3635: Allowing fixed audio decode->display mapping to avoid re-
88 * attaching outputs on every bdecode_stop/bdecode_start
89 *
90 * 158   1/25/10 3:11p vle
91 * SW7405-3486: Add feature to display bluescreen and mute audio when HDCP
92 * authentication fail.
93 *
94 * 157   12/20/09 4:55p randyjew
95 * SW7468-6:Add 7468 Support
96 *
97 * 156   12/16/09 5:34p jtna
98 * SW7335-547: update dynamic contrast when set to 0
99 *
100 * 155   12/11/09 4:30p mphillip
101 * SW7550-112: Merge 7550 changes to main branch
102 *
103 * Refsw_7550/4   12/4/09 6:43p chengli
104 * SW7550-108 : Enable 3:2 and 2:2 pull down when MAD is enabled
105 *
106 * Refsw_7550/3   11/30/09 4:47p chengli
107 * SW7550-64: remove HDCP error message
108 *
109 * Refsw_7550/2   11/25/09 3:27p chengli
110 * SW7550-64: remove compile warning
111 *
112 * Refsw_7550/1   11/19/09 12:02p chengli
113 * SW7550-64 : do not set DNR is the chip does not support DNR
114 *
115 * 154   12/3/09 2:45p jgarrett
116 * SW7405-3511: Adding compressed mute for outputs
117 *
118 * 153   11/19/09 8:02p jgarrett
119 * SW7405-3357: Adding audio output routing for decode and pcm playback
120 * prior to start
121 *
122 * 152   11/16/09 12:16p nickh
123 * SW7420-331: Dont open 2nd composite output for 7410
124 *
125 * 152   11/16/09 12:16p nickh
126 * SW7420-331: Dont open 2nd composite output for 7410
127 *
128 * 152   11/16/09 12:16p nickh
129 * SW7420-331: Dont open 2nd composite output for 7410
130 *
131 * 151   11/10/09 5:54p mward
132 * SW7400-2574: HD/SD sharpness optimizations incorporated in VDC,
133 * NEXUS_PictureCtrl_SetSharpnessValue() is no longer needed for simple
134 * sharpness setting.
135 *
136 * 150   11/10/09 4:58p mward
137 * SW7400-2574: When using the  NEXUS_PictureCtrl_SetSharpnessValue(), the
138 * quantity of sharpness must be set using lumaControlGain and
139 * chromaControlGain, the nPictureCtrlCommonSettings.sharpness is ignored
140 * by BVDC_Window_SetSharpness.
141 *
142 * 149   11/9/09 5:54p mward
143 * SW7400-2574:  Sharpness control optimizations.
144 *
145 * 148   11/4/09 1:59p mward
146 * SWDEPRECATED-3881: Restore 3 display operation.
147 *
148 * 147   10/23/09 5:49p mward
149 * SW7125-45: Enable AdvColorSettings on 7125.
150 *
151 * 146   10/22/09 10:51a jrubio
152 * SW7340-54: Add PEP for 7340/7342
153 *
154 * 145   10/20/09 4:09p erickson
155 * SW7405-3222: nexus no longer forces HD displays to be 16x9. it now has
156 * a NEXUS_DisplayAspectRatio_eAuto option. settop api does not have
157 * this, so we need to force HD to 16x9 for backward compatibility.
158 *
159 * 144   10/15/09 4:34p erickson
160 * SWDEPRECATED-3881: use NEXUS_PlatformConfiguration members to learn #
161 * of displays and windows available based on memory strapping options
162 *
163 * 143   10/9/09 7:56p nickh
164 * SW7420-382: Update BNR/MNR with optimized values
165 *
166 * 142   9/24/09 3:19p jgarrett
167 * SW7405-3072: Leaving HDMI audio always enabled regardless of hotplug
168 * state
169 *
170 * 141   9/24/09 2:24p vle
171 * SW7405-3078: Fix incorrect hdcp disable when setting hdmi output.
172 *
173 * 140   9/23/09 5:36p ahulse
174 * SW7405-2724: Switch MAD off when in playback pause to allow accurate
175 * frame stepping
176 *
177 * 139   9/1/09 5:39p erickson
178 * SW7420-303: set dynamic contrast gain shift based on Settop API units
179 *
180 * 138   8/18/09 6:44p katrep
181 * PR56109: Use calllbacks instead of using events for callbacks to the
182 * app
183 *
184 * 137   8/17/09 3:09p gmohile
185 * PR 56400 : Merge legacy vdc support to mainline
186 *
187 * 136   8/14/09 1:02p katrep
188 * PR57184: Coveirity issues
189 *
190 * 135   8/13/09 7:28p vle
191 * PR57708: Fix DVI_VALIDATE_EDID_FORMAT brutus configuration
192 *
193 * 134   8/4/09 1:28p vle
194 * PR49558: Add support to control av mute delay before and after format
195 * change separately.
196 *
197 * 133   7/29/09 12:19p katrep
198 * PR57184: Fixed brutus segfault on hdmi hdcp callback during
199 * shutdown.This could be the case of race condtion between scheduler
200 * event and uninit.
201 *
202 * 132   7/21/09 6:28p jrubio
203 * PR56905: revert back setting mad for Display 0 7335/7325
204 *
205 * 131   7/21/09 10:06a jrubio
206 * PR56905: Mad must be on first display for 7335/7325
207 *
208 * 130   7/7/09 3:45p katrep
209 * PR55769: hdmi_edid_bypass need to work with display
210 *
211 * 129   6/25/09 7:06p mward
212 * PR 47739:  Add composite2 setting to bdisplay_set().
213 *
214 * 128   6/24/09 3:44p erickson
215 * PR56233: call NEXUS_PictureCtrl_SetAdvColorSettings for 7325 and 7335
216 *
217 * 127   6/23/09 3:23p mward
218 * PR 56276: Coverity Defect ID:16503 DEADCODE
219 *
220 * 126   6/18/09 7:38p mward
221 * PR 53475: Failure of NEXUS_HdmiOutput_GetCecConfiguration() is normal
222 * if a compatible device is not connected.  Downgrade the associated
223 * error messages.
224 *
225 * 125   6/18/09 4:31p vishk
226 * PR 55748: (NEXUS) Clipping problem with bsettop Nexus shim
227 *
228 * 124   6/5/09 2:10p vishk
229 * PR 55748: (NEXUS) Clipping problem with bsettop Nexus shim
230 *
231 * 123   5/11/09 7:41p vle
232 * PR53373: Add HDMI 1.3a support, deep color, to Brutus/nexus
233 *
234 * 122   5/1/09 12:41p katrep
235 * PR54525: incorrect ar setting were getting applied to SD windows.
236 *
237 * 121   4/17/09 9:22a erickson
238 * PR54139: removed false ERR
239 *
240 * 120   4/14/09 12:02p katrep
241 * PR54139: Fixed coveiry issues
242 *
243 * 119   4/14/09 10:28a jtna
244 * PR51960: Fix memleak from hdmi cecEvent
245 *
246 * PR53373_DeepColor/3   5/11/09 6:28p vle
247 * PR53373: boutput_hdmi_get_color_depth is not needed. Use
248 * boutput_hdmi_get instead.
249 *
250 * PR53373_DeepColor/2   5/8/09 5:39p vle
251 * PR53373: Add Deep Color support to Brutus. Use GetSettings to get color
252 * depth
253 *
254 * PR53373_DeepColor/1   4/16/09 3:56p vle
255 * PR53373: Add HDMI 1.3a support, deep color, to Brutus/nexus
256 *
257 * 118   4/14/09 9:28a nickh
258 * PR52746: Only allow ANR and MAD settings to take effect on main window
259 * on main display for 7420
260 *
261 * 116   4/9/09 5:23p katrep
262 * PR52197: Lettter box and aspect ratio settings not getting applied
263 * correctly
264 *
265 * 115   3/16/09 4:35p erickson
266 * PR53271: set hdmi colorspace based on component colorspace (backward
267 * compatible)
268 *
269 * 114   3/12/09 11:47a nickh
270 * PR52746: Enable dynamic contrast
271 *
272 * 113   3/10/09 7:04p nickh
273 * PR52746: Add Advanced Picture controls for 7420, refine ANR values, and
274 * add demo mode
275 *
276 * 112   3/5/09 12:07p erickson
277 * PR48785: fix warnings for DTV systems
278 *
279 * 111   2/23/09 4:57p vle
280 * PR48785: Add CEC support to Nexus.
281 *
282 * 110   2/23/09 10:34a erickson
283 * PR52355: wrap ANR code with #if B_HAS_ANR
284 *
285 * 109   2/20/09 1:44p erickson
286 * PR52355: add ANR support
287 *
288 * 108   2/9/09 7:26p vle
289 * PR 45656, PR 51414: Do not assert when initializing HDCP settings. This
290 * prevents incorrect assertion if security is disabled
291 *
292 * 107   2/9/09 2:03p erickson
293 * PR51925: support 2 displays on 3548/3556
294 *
295 * 106   1/20/09 6:34p mward
296 * PR51333: Remove extra debug.
297 *
298 * 105   1/20/09 6:27p mward
299 * PR51333: Apply aspect ratio conversion to full-screen window each
300 * bdecode_window_set().  Can't assume display's window 0 is main and 1
301 * is PIP, could be swapped.
302 *
303 * 104   1/13/09 8:56a erickson
304 * PR50411: fix CRC for 3548
305 *
306 * 103   1/8/09 12:21p katrep
307 * PR50063: Add suppport dor Ac3 encode in Settop shim and burtus.
308 *
309 * 102   1/5/09 2:31p vishk
310 * PR 50411: CRC do not match on a few Divx streams - Undo previous
311 * changes.
312 *
313 * 101   12/30/08 12:30p vishk
314 * PR 50411: CRC do not match on a few Divx streams
315 *
316 * 100   12/17/08 11:42p erickson
317 * PR50501: HdmiOutputSettings now has pre and post format change delays
318 *
319 * 99   12/15/08 4:49p katrep
320 * PR50222: Add independent delay support for audio dacs. dac_output_delay
321 *
322 * 98   11/26/08 5:51p vle
323 * PR49583: Merge to main branch.
324 *
325 * PR49583/1   11/24/08 9:26p vle
326 * PR49583: Fix HDCP certification issue.
327 *
328 * 97   11/19/08 6:47p mward
329 * PR47739: Enable AdvColorSettings for 7400 (dynamic contrast not
330 * working).
331 *
332 * 96   11/13/08 1:47p jgarrett
333 * PR 48965: Allowing composite output on 3549b0
334 *
335 * 95   10/27/08 1:22p katrep
336 * PR48292: Fixed coveiry
337 *
338 * 94   10/22/08 3:12p erickson
339 * PR48023: settop pq api remains the same
340 *
341 * 92   10/20/08 4:07p erickson
342 * PR47994: remove debug code
343 *
344 * 91   10/20/08 3:51p erickson
345 * PR47994: fix panel output on 3548 B0 (no component)
346 *
347 * 90   10/20/08 12:38p erickson
348 * PR47994: default outputs connected to display0, avoid redundant
349 * RemoveOutput for rf
350 *
351 * 89   10/16/08 6:26p vsilyaev
352 * PR 47994: Fixed hdmi/dvi typo
353 *
354 * 88   10/16/08 12:15p jgarrett
355 * PR 47994: Fixing default dissplay configuration to match old settop api
356 *
357 * 87   9/23/08 1:12p katrep
358 * PR47150: Remove run time warning message
359 *
360 * 86   9/22/08 7:15p katrep
361 * PR47198:add support for spdif_output_delay,hdmi_output_delay run time
362 * variables
363 *
364 * 85   9/19/08 5:05p vishk
365 * PR 47150: Coverity Issues.
366 *
367 * 84   9/17/08 6:20p katrep
368 * PR47061: Add support for DTS encode
369 *
370 * 83   9/15/08 9:52a erickson
371 * PR45723: set forceCapture = true, set scaler bias for CRC
372 *
373 * 82   9/15/08 9:35a erickson
374 * PR45009: fix crash if hdmi not present
375 *
376 * 81   9/10/08 7:57p katrep
377 * PR46732: Force pcm for wma compressed. Fixed no audio on hdmi during
378 * pcm pb and i2s capture.
379 *
380 * 80   9/8/08 12:58p katrep
381 * PR44168: Removed run time error due to unimplemented cec code
382 *
383 * 79   9/2/08 7:44p katrep
384 * PR46457: Configure settop at run time, based on resources exposed by
385 * nexus platfrom.
386 *
387 * 78   8/26/08 8:30p katrep
388 * PR45577: Moved the HDMI audio ouput port settings from dispaly to
389 * decode.
390 *
391 * 77   8/14/08 11:46a jgarrett
392 * PR 44168: Adding cec_enable_receive function
393 *
394 * 76   8/13/08 7:08p katrep
395 * PR45577: Add supoort for 5.1 pcm audio on hdmi
396 *
397 * 75   8/6/08 3:36p katrep
398 * PR45009: display should not be connected to hdmi if its already
399 * connected. Fixed problem introduced by previous checkin.
400 *
401 * 74   8/4/08 10:20a vishk
402 * PR 45009: Video output handles are not being retained between bdisplay
403 * contexts.
404 *
405 * 73   7/31/08 6:58p katrep
406 * PR45082: Fixed broken PIP functionality
407 *
408 * 72   7/25/08 7:33p vishk
409 * PR 45082: bdecode_window_settings structure member 'visible' is not
410 * being auto-set to true.
411 *
412 * 71   7/23/08 9:39a erickson
413 * PR45059: protect DBG code against null settings->dvi
414 *
415 * 70   7/14/08 1:59p ssood
416 * PR42739: getting the audio dac handle via display structure
417 *
418 * 69   7/11/08 9:07a ssood
419 * PR42739: PR42739: commenting out debug code
420 * PR42739: Live IP High Jitter Support: store handles for I2S output &
421 * Audio DACs
422 *
423 * PR42739/2   7/10/08 10:51p ssood
424 * PR42739: commenting out debug code
425 *
426 * PR42739/1   7/10/08 10:21p ssood
427 * PR42739: Live IP High Jitter Support: store handles for I2S output &
428 * Audio DACs
429 *
430 * 68   7/3/08 6:09p erickson
431 * PR36068: impl vesa
432 *
433 * 67   6/27/08 9:30a erickson
434 * PR43653: add vesa support
435 *
436 * 66   6/25/08 5:16p jgarrett
437 * PR 36068: Enabling SCART output for 3556
438 *
439 * 65   6/25/08 12:56p erickson
440 * PR36068: DTV panel output for 93556
441 *
442 * 64   6/25/08 8:37a erickson
443 * PR43785: turn off forceCapture for CRC tests
444 *
445 * 63   6/23/08 2:44p erickson
446 * PR36068: fix warning
447 *
448 * 62   6/20/08 3:15p katrep
449 * PR42123: Print errors but do not return if the macrovision/dcs settings
450 * fail. Board may not opt options enabled.
451 *
452 * 61   6/19/08 3:16p vsilyaev
453 * PR 40921: There is no component output on the 93556 platform
454 *
455 * 60   6/18/08 10:13p erickson
456 * PR36068: add DTV panel support to shim (use component api)
457 *
458 * 59   6/13/08 5:04p erickson
459 * PR43110: reapply fix for PIP content mode
460 *
461 * 58   6/13/08 11:00a erickson
462 * PR43651: default some VESA values until NEXUS_HdmiOutputStatus is
463 * improved
464 *
465 * 57   6/5/08 5:59p jgarrett
466 * PR 43365: Fixing volume scaling
467 *
468 * 56   6/3/08 9:59a ahulse
469 * PR43266: Add support for DCS in nexus
470 *
471 * 55   5/29/08 11:58a erickson
472 * PR43117: apply default settings to nexus if settop api defaults are
473 * different
474 *
475 * 54   5/29/08 11:25a erickson
476 * PR43110: only apply content mode to Main, not PIP
477 *
478 * 53   5/23/08 11:50a erickson
479 * PR42998: set NEXUS_VideoWindowSettings.letterBoxAutoCut
480 *
481 * 52   5/22/08 5:30p erickson
482 * PR42982: default deinterlacer on
483 *
484 * 51   5/21/08 1:48p erickson
485 * PR42781: set correct default content_mode
486 *
487 * 50   5/21/08 1:38p erickson
488 * PR42783: fix component output RGB
489 *
490 * 49   5/16/08 3:38p erickson
491 * PR36068: clean up DBG output
492 *
493 * 48   5/12/08 2:10p erickson
494 * PR42266: set NEXUS_VideoWindowSettings.contentMode
495 *
496 * 47   4/24/08 2:59p jgarrett
497 * PR 42122: Setting HDMI volume with SPDIF
498 *
499 * 46   4/17/08 6:26p katrep
500 * PR41565: Adding more HDMI debug messages
501 *
502 * 45   4/13/08 10:03p katrep
503 * PR40824: Apply the VDC settings after all the window settings are
504 * updated,added debug
505 *
506 * 44   4/10/08 6:43p jgarrett
507 * PR 41565: Fixing lost audio on HDMI hotplug
508 *
509 * 43   4/10/08 10:07a erickson
510 * PR36068: coverity fix
511 *
512 * 42   4/9/08 1:19p erickson
513 * PR36068: allow format change without decode
514 *
515 * 41   4/9/08 9:16a erickson
516 * PR36068: fix 93563
517 *
518 * 40   4/8/08 3:56p katrep
519 * PR41122: Add support more display menu items
520 *
521 * 39   4/8/08 11:21a jgarrett
522 * PR 40024: Converting decode volume to linear scaling, clipping values
523 *
524 * 38   4/7/08 1:35p erickson
525 * PR40024: impl bdecode_set_audio_volume
526 *
527 * 37   4/2/08 6:55p jgarrett
528 * PR 41233: Adding HDCP Pj Checking
529 *
530 * 36   4/2/08 5:06p jgarrett
531 * PR 41233: Adding all HDMI settings
532 *
533 * 36   4/2/08 4:54p jgarrett
534 * PR 41233: Adding all HDMI settings
535 *
536 * 35   4/2/08 3:52p jrubio
537 * PR41191: add uninit func
538 *
539 * 34   4/1/08 6:59p jgarrett
540 * PR 41191: Revising shutdown logic
541 *
542 * 33   4/1/08 6:02p katrep
543 * PR41191: Add various input/output shutdowns
544 *
545 * 32   3/31/08 6:04p jgarrett
546 * PR 40606: Fixing HDMI behavior
547 *
548 * 31   3/25/08 7:43p vsilyaev
549 * PR 40862: Use nexus configuration to set supported formats
550 *
551 * 30   3/24/08 6:20p katrep
552 * PR40839: Added support for hdmi capabilities
553 *
554 * 29   3/21/08 8:39p katrep
555 * PR40824: Implemented support for PIP swapping.
556 *
557 * 28   3/21/08 12:12p erickson
558 * PR36068: set zorder
559 *
560 * 27   3/20/08 2:19p erickson
561 * PR36068: fix 3563
562 *
563 * 26   3/20/08 11:51a erickson
564 * PR36068: must remove RF output before changing format
565 *
566 * 25   3/20/08 9:42a jrubio
567 * PR40015: reworking some hdmi code
568 *
569 * 24   3/19/08 3:08p jrubio
570 * PR40015: add hdmi video/audio only
571 *
572 * 23   3/19/08 1:48p katrep
573 * PR40311: Added debug messages
574 *
575 * 22   3/17/08 11:37a erickson
576 * PR36068: stub new HDMI CEC functions
577 *
578 * 21   3/12/08 3:17p jgarrett
579 * PR 40017: Adding PCM support
580 *
581 * 20   3/11/08 11:10a erickson
582 * PR36068: impl vbi
583 *
584 * 19   3/10/08 5:51p erickson
585 * PR36068: added boutput_rf
586 *
587 * 18   1/31/08 1:53p erickson
588 * PR36068: default component output
589 *
590 * 17   1/24/08 3:13p jgarrett
591 * PR 38919: Renaming NEXUS_VideoWindow_Open
592 *
593 * 16   1/22/08 10:10a erickson
594 * PR36068: impl audio dac volume
595 *
596 * 15   1/9/08 2:53p erickson
597 * PR38535: change audio units
598 *
599 * 14   1/3/08 10:36a erickson
600 * PR36068: test num of audio dacs
601 *
602 * 13   1/2/08 9:55a erickson
603 * PR36068: Playback changes
604 *
605 * 12   12/3/07 4:59p erickson
606 * PR36068: rework audio, defer playback start until after decode start
607 *
608 * 11   11/27/07 11:16p erickson
609 * PR36068: don't default to DVO for 3563
610 *
611 * 10   11/27/07 9:20a erickson
612 * PR36068: update
613 *
614 * 9   11/14/07 1:27p erickson
615 * PR36068: remove unneeded g_graphic
616 *
617 * 8   11/12/07 3:57p erickson
618 * PR36068: update
619 *
620 * 7   11/12/07 2:34p erickson
621 * PR36068: update
622 *
623 * 6   10/19/07 12:25p erickson
624 * PR36068: added clone support
625 *
626 * 5   10/17/07 10:10a erickson
627 * PR36068: fix bad array index
628 *
629 * 4   10/17/07 9:45a erickson
630 * PR36068: don't terminate on failed RemoveOutput
631 *
632 * 3   10/16/07 1:17p erickson
633 * PR36068: update
634 *
635 * 2   10/16/07 12:35p erickson
636 * PR36068: brutus up over settop api/nexus
637 *
638 * 1   10/15/07 2:35p erickson
639 * PR36068: initial
640 *
641 ***************************************************************************/
642#include <stdlib.h>
643#include "bsettop_impl.h"
644#include "nexus_core_utils.h"
645
646#if B_N_DVI_OUTPUTS
647#include "nexus_hdmi_output_hdcp.h"
648#include "nexus_hdmi_output_cec.h"
649#endif
650
651BDBG_MODULE(display);
652
653struct bdisplay g_display[B_N_DISPLAYS];
654unsigned g_numDisplays=B_N_DISPLAYS;
655
656#if B_N_SPDIF_OUTPUTS
657struct boutput_spdif g_spdif[B_N_SPDIF_OUTPUTS];
658#endif
659#if B_N_COMPONENT_OUTPUTS
660struct boutput_component g_component[B_N_COMPONENT_OUTPUTS];
661#endif
662#if B_N_COMPOSITE_OUTPUTS
663struct boutput_composite g_composite[B_N_COMPOSITE_OUTPUTS];
664#endif
665#if B_N_SVIDEO_OUTPUTS
666struct boutput_svideo g_svideo[B_N_SVIDEO_OUTPUTS];
667#endif
668#if B_N_DVI_OUTPUTS
669struct boutput_hdmi g_hdmi[B_N_DVI_OUTPUTS];
670#endif
671#if B_N_RF_OUTPUTS
672struct boutput_rf g_rf[B_N_RF_OUTPUTS];
673static bresult b_set_rfm_audio_source(boutput_rf_t rf, bdisplay_t display);
674#endif
675
676#if B_N_AUDIO_DACS
677struct boutput_audio_dac g_audioDacs[B_N_AUDIO_DACS];
678#endif
679
680#ifdef B_HAS_IP
681#if B_N_I2S_OUTPUTS
682struct boutput_i2s g_i2sOutput[B_N_I2S_OUTPUTS];
683#endif
684#endif
685
686
687BDBG_OBJECT_ID(bdisplay);
688
689/* max video format on HD path. this is
690also setable with bsettop_get_config("max_hd_display_format").
691see below for values. */
692#if B_HAS_1080P_60
693NEXUS_VideoFormat g_max_hd_display_format = NEXUS_VideoFormat_e1080p;
694#elif B_HAS_1080P
695NEXUS_VideoFormat g_max_hd_display_format = NEXUS_VideoFormat_e1080p30hz;
696#elif B_DISPLAY_NO_HD_SUPPORT
697NEXUS_VideoFormat g_max_hd_display_format = NEXUS_VideoFormat_ePalG;
698#else
699NEXUS_VideoFormat g_max_hd_display_format = NEXUS_VideoFormat_e1080i;
700#endif
701
702static bresult bdisplay_p_set_output_volume(NEXUS_AudioOutput output, const baudio_volume *volume, baudio_volume *out_volume, bool force_mute);
703static void bsettop_p_display_apply_zorder(bdisplay_t display);
704static void bsettop_p_display_zorder_add(bdisplay_t display, bdecode_window_t window, unsigned zorder);
705static void bsettop_p_display_zorder_remove(bdisplay_t display , bdecode_window_t window);
706static void bsettop_p_display_zorder_set(bdisplay_t display , bdecode_window_t window, unsigned zorder);
707static bresult b_set_audio_output_timebase(NEXUS_AudioOutput output, NEXUS_Timebase outputTimebase);
708static void bdisplay_p_set_framerate_master(bdisplay_t display, bdecode_t master);
709static void bdisplay_p_set_output_timebase(bdisplay_t display, unsigned timebase);
710
711static bdecode_window_t gWindowMadOwner = NULL;
712
713#define SETTOP_MAX_PQ_LEVELS 6
714#define SETTOP_ANR_DNR_OFF_LEVEL -99
715
716#if B_N_DNR
717int32_t mnr_level[SETTOP_MAX_PQ_LEVELS] = {SETTOP_ANR_DNR_OFF_LEVEL,-75,-33,0,100,200};
718int32_t bnr_level[SETTOP_MAX_PQ_LEVELS] = {SETTOP_ANR_DNR_OFF_LEVEL,-75,-33,0,100,500};
719int32_t dcr_level[SETTOP_MAX_PQ_LEVELS] = {SETTOP_ANR_DNR_OFF_LEVEL,-90,-50,0,50,90};
720#endif
721
722#if B_HAS_ANR
723int32_t anr_level[6] = {SETTOP_ANR_DNR_OFF_LEVEL,-10,-5,0,5,10};
724#endif
725
726#if B_HAS_ANR || B_N_DNR
727typedef enum bsettop_pq_type
728{
729 pq_mnr=0,
730 pq_bnr,
731 pq_dcr,
732 pq_anr
733}bsettop_pq_type;
734
735int32_t bnexus_to_settop_pq_levels(int32_t value,bsettop_pq_type type)
736{
737   int32_t i=0;
738   int32_t *level;
739   switch (type) {
740#if B_N_DNR
741   case pq_mnr:
742        level = mnr_level;
743        break;
744   case pq_bnr:
745        level = bnr_level;
746        break;
747   case pq_dcr:
748        level = dcr_level;
749        break;
750#endif
751#if B_HAS_ANR
752   case pq_anr:
753        level = anr_level;
754        break;
755#endif
756   default: level = NULL;
757   }
758   if(level==NULL)
759   {
760     BDBG_ERR(("bnexus_to_magnum_pq_levels : Incorrect PQ type passed"));
761     goto bnexus_to_magnum_pq_levels_err;
762   }
763
764   for (i=0;i<SETTOP_MAX_PQ_LEVELS;i++) {
765       if(level[i]==value) 
766       break;
767   }
768bnexus_to_magnum_pq_levels_err:
769   return (i%SETTOP_MAX_PQ_LEVELS);
770}
771#endif
772
773bool is_panel_output()
774{
775    const char *str = bsettop_get_config("output_type");
776    return str && !b_strcmp(str, "panel");
777}
778
779#if B_N_DVI_OUTPUTS
780
781bresult boutput_hdmi_audio_mute(boutput_hdmi_t hdmi, bool mute)
782{
783    NEXUS_AudioOutput audioOutput;
784    NEXUS_AudioOutputSettings audioSettings;
785
786    audioOutput = NEXUS_HdmiOutput_GetAudioConnector(hdmi->handle);
787    NEXUS_AudioOutput_GetSettings(audioOutput, &audioSettings);
788    audioSettings.muted = mute;
789    NEXUS_AudioOutput_SetSettings(audioOutput, &audioSettings);
790
791    return b_ok;
792}
793
794static void bdisplay_p_disconnect_hdmi(bdisplay_t display, boutput_hdmi_t hdmi)
795{
796    NEXUS_Error rc;
797    NEXUS_DisplayHandle nDisplay;
798    NEXUS_DisplaySettings displaySettings;
799
800    BDBG_ASSERT(NULL != hdmi);
801    BDBG_ASSERT(NULL != display);
802
803    if ( hdmi->display != display || !hdmi->connected )
804    {
805        BDBG_ERR(("Invalid disconnect HDMI request"));
806        return;
807    }
808
809    nDisplay = display->nDisplay;
810
811    BDBG_MSG(("Detaching HDMI from display %p", display));
812
813    if ( hdmi->desired.hdcp )
814    {
815        (void)NEXUS_HdmiOutput_DisableHdcpAuthentication(hdmi->handle);
816    }
817
818    NEXUS_Display_GetSettings(nDisplay, &displaySettings);
819
820    rc= NEXUS_Display_RemoveOutput(nDisplay, NEXUS_HdmiOutput_GetVideoConnector(hdmi->handle));
821    if (rc) BSETTOP_ERROR(berr_external_error); /* keep going */
822
823#if 0 /* Leave audio alone on hotplug */
824    bdisplay_p_enable_audio(display, false);
825    rc = NEXUS_AudioOutput_RemoveAllInputs(NEXUS_HdmiOutput_GetAudioConnector(hdmi->handle));
826    if(rc) {BSETTOP_ERROR(BERR_UNKNOWN);}
827    bdisplay_p_enable_audio(display, true);
828#endif
829
830    /* We have to do Display SetSettings because the HDMI calls do not refresh the SetSettings */
831    rc = NEXUS_Display_SetSettings(nDisplay, &displaySettings);
832    if(rc){rc = BERR_TRACE(rc);}
833
834    hdmi->connected = false;
835}
836
837static void bdisplay_p_connect_hdmi(bdisplay_t display, boutput_hdmi_t hdmi)
838{
839    NEXUS_Error rc;
840    NEXUS_DisplayHandle nDisplay;
841    NEXUS_DisplaySettings displaySettings;
842
843
844    BDBG_ASSERT(NULL != hdmi);
845    BDBG_ASSERT(NULL != display);
846
847    nDisplay = display->nDisplay;
848
849    NEXUS_Display_GetSettings(nDisplay, &displaySettings);
850
851    BDBG_MSG(("Attaching HDMI to display %p", display));
852
853    rc = NEXUS_Display_AddOutput(nDisplay, NEXUS_HdmiOutput_GetVideoConnector(hdmi->handle));
854    if (rc)
855    {
856        BSETTOP_ERROR(rc); return;
857    }
858
859#if 0 /* Leave audio alone on hotplug */
860    bdisplay_p_enable_audio(display, false);
861
862    /* remove any inputs if connected */
863    rc = NEXUS_AudioOutput_RemoveAllInputs(NEXUS_HdmiOutput_GetAudioConnector(hdmi->handle));
864    if(rc) {BSETTOP_ERROR(BERR_UNKNOWN);}
865
866    if ( hdmi->desired.hdmi_audio_mode == boutput_hdmi_audio_mode_pcm )
867    {
868        BDBG_MSG(("Attaching HDMI audio to mixer"));
869        rc = NEXUS_AudioOutput_AddInput(NEXUS_HdmiOutput_GetAudioConnector(hdmi->handle),
870                                        NEXUS_AudioMixer_GetConnector(display->nAudioMixer));
871        if (rc)
872        {
873            rc = BERR_TRACE(rc);
874        }
875    }
876    else
877    {
878        BDBG_MSG(("NOT Attaching HDMI audio to mixer,audio must be multichannel or compressed %d",hdmi->desired.hdmi_audio_mode));
879    }
880
881    bdisplay_p_enable_audio(display, true);
882#endif
883
884    /* We have to do Display SetSettings because the HDMI calls do not refresh the SetSettings */
885    rc = NEXUS_Display_SetSettings(nDisplay, &displaySettings);
886    if (rc)
887    {
888        rc = BERR_TRACE(rc);
889    }
890
891    hdmi->connected = true;
892
893    if ( hdmi->desired.hdcp )
894    {
895        /* Start HDCP if connected */
896        rc = NEXUS_HdmiOutput_StartHdcpAuthentication(hdmi->handle);
897        if (rc)
898        {
899            rc = BERR_TRACE(rc);
900        }
901    }
902
903    if ( display->settings.spdif )
904    {
905        boutput_spdif_set_audio_volume(display->settings.spdif, &display->settings.spdif->volume);
906    }
907}
908
909static void bdisplay_p_hdmi_hotplug_callback(void *pParam, int iParam)
910{
911    BSTD_UNUSED(iParam);
912    B_Event_Set(pParam);
913}
914
915void bdisplay_p_hdmi_hotplug_handler(void *context)
916{
917    boutput_hdmi_t hdmi = context;
918    NEXUS_HdmiOutputStatus status;
919    NEXUS_HdmiOutputHandle nHdmi;
920    bdisplay_t display;
921    BDBG_ASSERT(NULL != hdmi);
922
923    display = hdmi->display;
924    nHdmi = hdmi->handle;
925
926
927    NEXUS_HdmiOutput_GetStatus(nHdmi, &status);
928
929    BDBG_MSG(("HDMI Hotplug Event status %d connected %d", status.connected, hdmi->connected));
930
931    /* Check for connection status change */
932    if ( hdmi->connected != status.connected )
933    {
934        if ( status.connected )
935        {
936            /* set preferred format from new receiver */
937            hdmi->desired.edid_preferred_format = b_nexus2displayformat(status.preferredVideoFormat, &hdmi->desired.vesa_settings);
938
939            BDBG_MSG(("HDMI Hotplug - Notifying application"));
940            if ( hdmi->desired.hdmi_hotplug_callback )
941            {
942#if 0
943                b_unlock();
944                hdmi->desired.hdmi_hotplug_callback(hdmi->desired.callback_context);
945                b_lock();
946#endif
947                b_callback_fire(hdmi->hotplugCallback);
948            }
949        }
950        else
951        {
952            bdisplay_p_disconnect_hdmi(display, hdmi);
953            BDBG_MSG(("HDMI Disconnect - Notifying application"));
954            if ( hdmi->desired.hdmi_disconnect_callback )
955            {
956#if 0
957                b_unlock();
958                hdmi->desired.hdmi_disconnect_callback(hdmi->desired.callback_context);
959                b_lock();
960#endif
961                b_callback_fire(hdmi->disconnectCalllback);
962            }
963        }
964    }
965}
966
967static void bdisplay_p_hdmi_hotplug_app_handler(void *context,int param)
968{
969    boutput_hdmi_t hdmi = context;
970    BSTD_UNUSED(param);
971    hdmi->desired.hdmi_hotplug_callback(hdmi->desired.callback_context);
972}
973static void bdisplay_p_hdmi_disconnect_app_handler(void *context,int param)
974{
975    boutput_hdmi_t hdmi = context;
976    BSTD_UNUSED(param);
977    hdmi->desired.hdmi_disconnect_callback(hdmi->desired.callback_context);
978}
979
980static void bdisplay_p_hdcp_status_callback(void *pParam, int iParam)
981{
982    BSTD_UNUSED(iParam);
983    B_Event_Set(pParam);
984}
985
986static void bdisplay_p_hdcp_retry(void *context)
987{
988    boutput_hdmi_t hdmi = context;
989    BDBG_ASSERT(NULL != context);
990    hdmi->hdcpTimer = NULL;
991    if ( hdmi->desired.hdcp  )
992    {
993        BDBG_WRN(("Restarting HDCP authentication"));
994        NEXUS_HdmiOutput_StartHdcpAuthentication(hdmi->handle);
995    }
996}
997
998static void bdisplay_p_hdmi_hdcp_handler(void *context)
999{
1000    boutput_hdmi_t hdmi = context;
1001    NEXUS_HdmiOutputHdcpStatus hdcpStatus;
1002    NEXUS_DisplaySettings displaySettings;
1003    NEXUS_HdmiOutputSettings hdmiOutputSettings;
1004
1005    BDBG_ASSERT(NULL != context);
1006
1007    BDBG_MSG(("HDCP status change"));
1008
1009    if ( !hdmi->desired.hdcp )
1010    {
1011        return;     /* Bail out if HDCP is disabled now */
1012    }
1013
1014    NEXUS_HdmiOutput_GetHdcpStatus(hdmi->handle, &hdcpStatus);
1015
1016    switch ( hdcpStatus.hdcpState )
1017    {
1018    case NEXUS_HdmiOutputHdcpState_eUnauthenticated:
1019        /* Display bluescreen and mute audio unless user disable this feature */
1020        if (!hdmi->desired.hdcp_disable_blue_screen)
1021        {
1022            NEXUS_Display_GetSettings(hdmi->display->nDisplay, &displaySettings);
1023            displaySettings.background = 0xff0000ff; /* blue */
1024            NEXUS_Display_SetSettings(hdmi->display->nDisplay, &displaySettings);
1025
1026            NEXUS_HdmiOutput_GetSettings(hdmi->handle, &hdmiOutputSettings);
1027            hdmiOutputSettings.syncOnly = true;
1028            NEXUS_HdmiOutput_SetSettings(hdmi->handle, &hdmiOutputSettings);
1029
1030            boutput_hdmi_audio_mute(hdmi, true);
1031        }
1032        break;
1033
1034    case NEXUS_HdmiOutputHdcpState_eR0LinkFailure:
1035    case NEXUS_HdmiOutputHdcpState_ePjLinkIntegrityFailure:
1036    case NEXUS_HdmiOutputHdcpState_eRiLinkIntegrityFailure:
1037    case NEXUS_HdmiOutputHdcpState_eRepeaterAuthenticationFailure:
1038
1039        /* Display bluescreen and mute audio unless user disable this feature */
1040        if (!hdmi->desired.hdcp_disable_blue_screen)
1041        {
1042            NEXUS_Display_GetSettings(hdmi->display->nDisplay, &displaySettings);
1043            displaySettings.background = 0xff0000ff; /* blue */
1044            NEXUS_Display_SetSettings(hdmi->display->nDisplay, &displaySettings);
1045
1046            NEXUS_HdmiOutput_GetSettings(hdmi->handle, &hdmiOutputSettings);
1047            hdmiOutputSettings.syncOnly = true;
1048            NEXUS_HdmiOutput_SetSettings(hdmi->handle, &hdmiOutputSettings);
1049
1050            boutput_hdmi_audio_mute(hdmi, true);
1051        }
1052
1053        /* Retry auth if requested */
1054        if ( hdmi->desired.hdcp_failure_retry_delay > 0 )
1055        {
1056            if ( NULL != hdmi->hdcpTimer )
1057            {
1058                b_timer_cancel(hdmi->hdcpTimer);
1059            }
1060            b_timer_schedule(hdmi->desired.hdcp_failure_retry_delay, bdisplay_p_hdcp_retry, hdmi);
1061        }
1062        break;
1063
1064    case NEXUS_HdmiOutputHdcpState_eLinkAuthenticated:
1065    case NEXUS_HdmiOutputHdcpState_eEncryptionEnabled:
1066        /* clear bluescreen */
1067        if (!hdmi->desired.hdcp_disable_blue_screen)
1068        {
1069            NEXUS_Display_GetSettings(hdmi->display->nDisplay, &displaySettings);
1070            displaySettings.background = 0xff000000; /* clear blue screen*/
1071            NEXUS_Display_SetSettings(hdmi->display->nDisplay, &displaySettings);
1072
1073            NEXUS_HdmiOutput_GetSettings(hdmi->handle, &hdmiOutputSettings);
1074            hdmiOutputSettings.syncOnly = false;
1075            NEXUS_HdmiOutput_SetSettings(hdmi->handle, &hdmiOutputSettings);
1076
1077            boutput_hdmi_audio_mute(hdmi, false);
1078        }
1079        break;
1080
1081    default:
1082        break;
1083    }
1084
1085    if ( hdmi->desired.hdmi_hdcp_status_callback )
1086    {
1087#if 0
1088        b_unlock();
1089        hdmi->desired.hdmi_hdcp_status_callback(hdmi->desired.callback_context);
1090        b_lock();
1091#endif
1092        b_callback_fire(hdmi->hdcpCallback);
1093    }
1094}
1095
1096static void bdisplay_p_hdmi_hdcp_app_handler(void *context,int param)
1097{
1098    boutput_hdmi_t hdmi = context;
1099    BSTD_UNUSED(param);
1100    BDBG_WRN(("hdcp callback"));
1101    hdmi->desired.hdmi_hdcp_status_callback(hdmi->desired.callback_context);
1102}
1103
1104static void bdisplay_p_hdmi_cec_callback(void *pParam, int iParam)
1105{
1106    BSTD_UNUSED(iParam);
1107
1108    /*B_Event_Set(pParam);*/
1109    b_callback_fire(pParam);
1110}
1111
1112static void bdisplay_p_hdmi_cec_handler(void *context,int param)
1113{
1114    boutput_hdmi_t hdmi = context;
1115
1116    BDBG_ASSERT(NULL != hdmi);
1117    BSTD_UNUSED(param);
1118
1119    BDBG_MSG(("HDMI CEC Message Callback - Notifying application"));
1120    if ( hdmi->desired.hdmi_cec_message_callback )
1121    {
1122        /*b_unlock();*/
1123        hdmi->desired.hdmi_cec_message_callback(hdmi->desired.callback_context);
1124        /*b_lock();*/
1125    }
1126}
1127
1128#endif /* B_N_DVI_OUTPUTS */
1129
1130void bdisplay_p_init()
1131{
1132    unsigned i,j;
1133    NEXUS_PlatformConfiguration platformConfig;
1134    NEXUS_PlatformSettings platformSettings;
1135    const char *outputDelay=NULL;
1136
1137    NEXUS_Platform_GetConfiguration(&platformConfig);
1138    NEXUS_Platform_GetSettings(&platformSettings);
1139
1140    BKNI_Memset(g_display, 0, sizeof(g_display));
1141    g_numDisplays = (platformConfig.supportedDisplay[0]?1:0) +
1142                    ((B_N_DISPLAYS > 1) ? (platformConfig.supportedDisplay[1]?1:0):0) +
1143                    ((B_N_DISPLAYS > 2) ? (platformConfig.supportedDisplay[2]?1:0):0);
1144
1145    for (i=0;i<g_numDisplays;i++) {
1146        g_display[i].index = i;
1147        g_display[i].settings.content_mode = bdisplay_content_mode_box;
1148        g_display[i].numWindowsSupported = platformConfig.numWindowsPerDisplay;
1149        g_display[i].outputTimebase = 0xffffffff;
1150        for (j=0;j<g_display[i].numWindowsSupported;j++) {
1151            bdecode_window_t window = &g_display[i].window[j];
1152            window->display = &g_display[i];
1153            window->settings.position.width = 720;
1154            window->settings.position.height = 480;
1155            window->settings.zorder = j;
1156            window->settings.deinterlacer = (j==0 && i==0);
1157            window->playbackDeinterlacer = false;
1158        }
1159    }
1160
1161#if B_N_SPDIF_OUTPUTS
1162    BKNI_Memset(g_spdif, 0, sizeof(g_spdif));
1163    for (i=0;i<B_N_SPDIF_OUTPUTS;i++) {
1164        g_spdif[i].handle = platformConfig.outputs.spdif[i];
1165        g_display[i].settings.spdif = &g_spdif[i];
1166        g_spdif[i].display = &g_display[i];
1167        g_spdif[i].volume.left = g_spdif[i].volume.right = BAUDIO_LEVEL_MAX;
1168        outputDelay = bsettop_get_config("spdif_output_delay");
1169        if(NULL != outputDelay)
1170        {
1171            NEXUS_AudioOutputSettings nOutputSettings;
1172            NEXUS_AudioOutput_GetSettings(NEXUS_SpdifOutput_GetConnector(g_spdif[i].handle),&nOutputSettings);
1173            nOutputSettings.additionalDelay = atoi(outputDelay);
1174            BDBG_MSG(("Spdif output delay %d",nOutputSettings.additionalDelay));
1175            NEXUS_AudioOutput_SetSettings(NEXUS_SpdifOutput_GetConnector(g_spdif[i].handle),&nOutputSettings);
1176        }
1177    }
1178#endif
1179
1180#if B_N_AUDIO_DACS
1181    BKNI_Memset(g_audioDacs, 0, sizeof(g_audioDacs));
1182    for (i=0;i<B_N_AUDIO_DACS;i++) {
1183        g_audioDacs[i].handle = platformConfig.outputs.audioDacs[i];
1184        outputDelay = bsettop_get_config("dac_output_delay");
1185        if(NULL != outputDelay)
1186        {
1187            NEXUS_AudioOutputSettings nOutputSettings;
1188            NEXUS_AudioOutput_GetSettings(NEXUS_AudioDac_GetConnector(g_audioDacs[i].handle),&nOutputSettings);
1189            nOutputSettings.additionalDelay = atoi(outputDelay);
1190            BDBG_MSG(("Dac output delay %d",nOutputSettings.additionalDelay));
1191            NEXUS_AudioOutput_SetSettings(NEXUS_AudioDac_GetConnector(g_audioDacs[i].handle),&nOutputSettings);
1192        }
1193    }
1194#endif
1195
1196#if B_N_COMPONENT_OUTPUTS
1197    BKNI_Memset(g_component, 0, sizeof(g_component));
1198    for (i=0;i<B_N_COMPONENT_OUTPUTS;i++) {
1199#if NEXUS_NUM_PANEL_OUTPUTS
1200        g_component[i].panelHandle = platformConfig.outputs.panel[i];
1201        if (is_panel_output()) {
1202            g_component[i].videoOutput = NEXUS_PanelOutput_GetConnector(g_component[i].panelHandle);
1203        }
1204        else
1205        {
1206            #if NEXUS_NUM_SCART_INPUTS
1207            /* hack for 3556 to display on scart -- it's an SD output, so brutus must run sd modes only */
1208            g_component[i].videoOutput = NEXUS_ScartInput_GetVideoOutputConnector(platformConfig.inputs.scart[1]);
1209            #elif NEXUS_NUM_COMPONENT_OUTPUTS
1210            /* Normal case 3548 A0 */
1211            g_component[i].videoOutput = NEXUS_ComponentOutput_GetConnector(platformConfig.outputs.component[0]);
1212            #else
1213            /* Normal case 3548 B0 */
1214            g_component[i].videoOutput = NEXUS_CompositeOutput_GetConnector(platformConfig.outputs.composite[0]);
1215            #endif
1216        }
1217#else
1218        g_component[i].handle = platformConfig.outputs.component[i];
1219        g_component[i].desired.type = boutput_component_type_yprpb;
1220        g_component[i].videoOutput = NEXUS_ComponentOutput_GetConnector(g_component[i].handle);
1221#endif
1222    }
1223#endif
1224#if B_N_COMPOSITE_OUTPUTS
1225    BKNI_Memset(g_composite, 0, sizeof(g_composite));
1226    for (i=0;i<B_N_COMPOSITE_OUTPUTS;i++) {
1227        g_composite[i].handle = platformConfig.outputs.composite[i];
1228    }
1229#endif
1230#if B_N_SVIDEO_OUTPUTS
1231    BKNI_Memset(g_svideo, 0, sizeof(g_svideo));
1232    for (i=0;i<B_N_SVIDEO_OUTPUTS;i++) {
1233        g_svideo[i].handle = platformConfig.outputs.svideo[i];
1234    }
1235#endif
1236#if B_N_DVI_OUTPUTS
1237    {
1238        /* NEXUS_HdmiOutputHdcpSettings >  1024 bytes */
1239        NEXUS_HdmiOutputHdcpSettings * pHdcpSettings=NULL;
1240        pHdcpSettings = BKNI_Malloc(sizeof(NEXUS_HdmiOutputHdcpSettings));
1241        if(!pHdcpSettings)
1242        {
1243            BDBG_ERR(("Unable to allocate memory"));
1244            BDBG_ASSERT(NULL);
1245        }
1246
1247        BKNI_Memset(g_hdmi, 0, sizeof(g_hdmi));
1248
1249        for (i=0;i<B_N_DVI_OUTPUTS;i++)
1250        {
1251            NEXUS_Error rc;
1252            NEXUS_HdmiOutputSettings hdmiSettings;
1253
1254            g_hdmi[i].handle = platformConfig.outputs.hdmi[i];
1255            /* set HDMI handles here */
1256            g_display[i].settings.dvi= &g_hdmi[i];
1257
1258            g_hdmi[i].event = B_Event_Create(NULL);
1259            BDBG_ASSERT(NULL != g_hdmi[i].event);
1260
1261            g_hdmi[i].hdcpEvent = B_Event_Create(NULL);
1262            BDBG_ASSERT(NULL != g_hdmi[i].hdcpEvent);
1263
1264            g_hdmi[i].eventId = b_event_register(g_hdmi[i].event, bdisplay_p_hdmi_hotplug_handler, &g_hdmi[i]);
1265            g_hdmi[i].hdcpEventId = b_event_register(g_hdmi[i].hdcpEvent, bdisplay_p_hdmi_hdcp_handler, &g_hdmi[i]);
1266
1267#if 0
1268            g_hdmi[i].cecEvent = B_Event_Create(NULL);
1269            BDBG_ASSERT(NULL != g_hdmi[i].cecEvent);
1270
1271            g_hdmi[i].cecEventId = b_event_register(g_hdmi[i].cecEvent, bdisplay_p_hdmi_cec_handler, &g_hdmi[i]);
1272#endif
1273            g_hdmi[i].hotplugCallback = b_callback_create(&g_hdmi[i],bdisplay_p_hdmi_hotplug_app_handler,&g_hdmi[i],0);
1274            BDBG_ASSERT(NULL != g_hdmi[i].hotplugCallback);
1275            g_hdmi[i].disconnectCalllback = b_callback_create(&g_hdmi[i],bdisplay_p_hdmi_disconnect_app_handler,&g_hdmi[i],0);
1276            BDBG_ASSERT(NULL != g_hdmi[i].disconnectCalllback );
1277            g_hdmi[i].hdcpCallback = b_callback_create(&g_hdmi[i],bdisplay_p_hdmi_hdcp_app_handler,&g_hdmi[i],0);
1278            BDBG_ASSERT(NULL != g_hdmi[i].hdcpCallback);
1279            g_hdmi[i].cecCalllback = b_callback_create(&g_hdmi[i],bdisplay_p_hdmi_cec_handler,&g_hdmi[i],0);
1280            BDBG_ASSERT(NULL != g_hdmi[i].cecCalllback);
1281
1282
1283            NEXUS_HdmiOutput_GetSettings(g_hdmi[i].handle, &hdmiSettings);
1284            hdmiSettings.hotplugCallback.callback = bdisplay_p_hdmi_hotplug_callback;
1285            hdmiSettings.hotplugCallback.context = g_hdmi[i].event;
1286            hdmiSettings.cecCallback.callback = bdisplay_p_hdmi_cec_callback;
1287            /*hdmiSettings.cecCallback.context = g_hdmi[i].cecEvent;*/
1288            hdmiSettings.cecCallback.context = g_hdmi[i].cecCalllback;
1289            rc = NEXUS_HdmiOutput_SetSettings(g_hdmi[i].handle, &hdmiSettings);
1290            BDBG_ASSERT(rc == NEXUS_SUCCESS);
1291
1292            /* Initialize/install HDCP callback to notify app */
1293            NEXUS_HdmiOutput_GetHdcpSettings(g_hdmi[i].handle, pHdcpSettings);
1294            pHdcpSettings->stateChangedCallback.callback = bdisplay_p_hdcp_status_callback;
1295            pHdcpSettings->stateChangedCallback.context = g_hdmi[i].hdcpEvent;
1296            pHdcpSettings->failureCallback.callback = bdisplay_p_hdcp_status_callback;
1297            pHdcpSettings->failureCallback.context = g_hdmi[i].hdcpEvent;
1298            /* TO DO: Add successCallback */
1299            rc = NEXUS_HdmiOutput_SetHdcpSettings(g_hdmi[i].handle, pHdcpSettings);
1300            if (rc != NEXUS_SUCCESS)
1301                BDBG_ERR(("Error initializing hdmi_output_hdcp settings"));
1302
1303            outputDelay = bsettop_get_config("hdmi_output_delay");
1304            if (NULL != outputDelay)
1305            {
1306                NEXUS_AudioOutputSettings nOutputSettings;
1307                NEXUS_AudioOutput_GetSettings(NEXUS_HdmiOutput_GetAudioConnector(g_hdmi[i].handle),&nOutputSettings);
1308                nOutputSettings.additionalDelay = atoi(outputDelay);
1309                BDBG_MSG(("HDMI output delay %d",nOutputSettings.additionalDelay));
1310                NEXUS_AudioOutput_SetSettings(NEXUS_HdmiOutput_GetAudioConnector(g_hdmi[i].handle),&nOutputSettings);
1311            }
1312        }
1313        if(pHdcpSettings)
1314            BKNI_Free(pHdcpSettings);
1315    }
1316#endif
1317#if B_N_RF_OUTPUTS
1318    BKNI_Memset(g_rf, 0, sizeof(g_rf));
1319    for (i=0;i<B_N_RF_OUTPUTS;i++) {
1320        g_rf[i].handle = platformConfig.outputs.rfm[i];
1321        g_rf[i].desired.channel = 3;
1322        g_rf[i].desired.country[0] = 'U';
1323        g_rf[i].desired.country[1] = 'S';
1324    }
1325#endif
1326
1327#if B_N_COMPONENT_OUTPUTS
1328    g_display[0].settings.component = &g_component[0];
1329#endif
1330#if !NEXUS_DTV_PLATFORM
1331#if B_N_COMPOSITE_OUTPUTS
1332    g_display[1].settings.composite = &g_composite[0];
1333#endif
1334#if B_N_SVIDEO_OUTPUTS
1335    g_display[0].settings.svideo = &g_svideo[0];
1336#endif
1337#if B_N_RF_OUTPUTS
1338    g_display[0].settings.rf = &g_rf[0];
1339#endif
1340#endif
1341}
1342
1343void bdisplay_p_uninit()
1344{
1345    unsigned i= 0;
1346
1347    /* Go through the Display list and free the Nexus Handle*/
1348    for (i=0;i<g_numDisplays;i++)
1349    {
1350        if (g_display[i].nDisplay)
1351            bdisplay_close(&g_display[i]);
1352    }
1353
1354#if B_N_DVI_OUTPUTS
1355    {
1356        /* NEXUS_HdmiOutputHdcpSettings >  1024 bytes */
1357        NEXUS_HdmiOutputHdcpSettings * pHdcpSettings=NULL;
1358        pHdcpSettings = BKNI_Malloc(sizeof(NEXUS_HdmiOutputHdcpSettings));
1359        if (!pHdcpSettings)
1360        {
1361            BDBG_ERR(("Unable to allocate memory"));
1362            BDBG_ASSERT(NULL);
1363        }
1364
1365        for (i=0;i<B_N_DVI_OUTPUTS;i++)
1366        {
1367            NEXUS_Error rc;
1368            NEXUS_HdmiOutputSettings hdmiSettings;
1369
1370            NEXUS_StopCallbacks(g_hdmi[i].handle);
1371
1372            /* Initialize/install HDCP callback to notify app */
1373            NEXUS_HdmiOutput_GetHdcpSettings(g_hdmi[i].handle, pHdcpSettings);
1374            pHdcpSettings->stateChangedCallback.callback = NULL;
1375            pHdcpSettings->failureCallback.callback = NULL;
1376            pHdcpSettings->stateChangedCallback.context = NULL;
1377            pHdcpSettings->failureCallback.context = NULL;
1378            rc = NEXUS_HdmiOutput_SetHdcpSettings(g_hdmi[i].handle, pHdcpSettings);
1379            if (rc != NEXUS_SUCCESS)
1380                BDBG_ERR(("Error uninit hdmi_output_hdcp settings"));
1381
1382            NEXUS_HdmiOutput_GetSettings(g_hdmi[i].handle, &hdmiSettings);
1383            hdmiSettings.hotplugCallback.callback = NULL;
1384            hdmiSettings.hotplugCallback.context = NULL;
1385            rc = NEXUS_HdmiOutput_SetSettings(g_hdmi[i].handle, &hdmiSettings);
1386
1387            if ( NULL != g_hdmi[i].hdcpTimer )
1388            {
1389                b_timer_cancel(g_hdmi[i].hdcpTimer);
1390            }
1391#if 0
1392            b_event_unregister(g_hdmi[i].cecEventId);
1393            B_Event_Destroy(g_hdmi[i].cecEvent);
1394#endif
1395            b_event_unregister(g_hdmi[i].eventId);
1396            b_event_unregister(g_hdmi[i].hdcpEventId);
1397            B_Event_Destroy(g_hdmi[i].event);
1398            B_Event_Destroy(g_hdmi[i].hdcpEvent);
1399
1400
1401            b_callback_destroy(g_hdmi[i].hotplugCallback);
1402            b_callback_destroy(g_hdmi[i].disconnectCalllback);
1403            b_callback_destroy(g_hdmi[i].cecCalllback);
1404            b_callback_destroy(g_hdmi[i].hdcpCallback);
1405        }
1406        BKNI_Free(pHdcpSettings);
1407        BKNI_Memset(g_hdmi, 0, sizeof(g_hdmi));
1408    }
1409#endif
1410
1411}
1412
1413bdisplay_t bdisplay_open(bobject_t display_id)
1414{
1415    unsigned index = B_ID_GET_INDEX(display_id);
1416    bdisplay_t display;
1417    NEXUS_PlatformConfiguration platformConfig;
1418    NEXUS_DisplaySettings displaySettings;
1419    bdisplay_settings temp_settings;
1420
1421    if (index >= g_numDisplays) {
1422        BSETTOP_ERROR(berr_not_available);
1423        return NULL;
1424    }
1425    display = &g_display[index];
1426    if (display->nDisplay) {
1427        BSETTOP_ERROR(berr_not_available);
1428        return NULL;
1429    }
1430
1431    BDBG_OBJECT_SET(display, bdisplay);
1432
1433    NEXUS_Display_GetDefaultSettings(&displaySettings);
1434    if (is_panel_output() && index == 0) {
1435        displaySettings.displayType = NEXUS_DisplayType_eLvds;
1436        displaySettings.format = NEXUS_VideoFormat_eCustom0;
1437    }
1438    else {
1439        displaySettings.displayType = NEXUS_DisplayType_eAuto;
1440        displaySettings.format = NEXUS_VideoFormat_eNtsc;
1441    }
1442    display->nDisplay = NEXUS_Display_Open(index, &displaySettings);
1443    if (!display->nDisplay) {
1444        BSETTOP_ERROR(berr_not_available);
1445        goto error;
1446    }
1447    display->nAudioMixer = NEXUS_AudioMixer_Open(NULL);
1448    if (!display->nAudioMixer) {
1449        BSETTOP_ERROR(berr_not_available);
1450        goto error;
1451    }
1452
1453    /* DAC's are always connected to pcm mixer */
1454    NEXUS_Platform_GetConfiguration(&platformConfig);
1455    if (index < NEXUS_NUM_AUDIO_DACS) {
1456        display->audioDac.handle = platformConfig.outputs.audioDacs[index];
1457    }
1458    if (display->audioDac.handle) {
1459        NEXUS_AudioOutput_AddInput(
1460            NEXUS_AudioDac_GetConnector(display->audioDac.handle),
1461            NEXUS_AudioMixer_GetConnector(display->nAudioMixer)
1462            );
1463    }
1464
1465#if B_N_DVI_OUTPUTS
1466    if (display->settings.dvi)
1467    {
1468        display->settings.dvi->display = display;
1469        display->settings.dvi->connected = false;
1470        /* If PCM, add HDMI to the mixer now before hotplug */
1471        if ( display->settings.dvi->desired.hdmi_audio_mode == boutput_hdmi_audio_mode_pcm )
1472        {
1473            NEXUS_AudioOutput_AddInput(NEXUS_HdmiOutput_GetAudioConnector(display->settings.dvi->handle),
1474                                       NEXUS_AudioMixer_GetConnector(display->nAudioMixer));
1475        }
1476    }
1477#endif /* B_N_DVI_OUTPUTS */
1478
1479#if 1 /* Cannot set dac audio level here */
1480    display->volume.left = BAUDIO_LEVEL_MAX;
1481    display->volume.right = BAUDIO_LEVEL_MAX;
1482    display->volume.muted = false;
1483    bdisplay_set_dac_audio_volume(display, &display->volume);
1484#endif
1485
1486    temp_settings = display->settings;
1487    display->settings.component = NULL;
1488    display->settings.composite = NULL;
1489    display->settings.composite2 = NULL;
1490    display->settings.svideo = NULL;
1491    display->settings.rf = NULL;
1492    bdisplay_set(display, &temp_settings);
1493
1494    return display;
1495
1496error:
1497    bdisplay_close(display);
1498    return NULL;
1499}
1500
1501void bdisplay_close(bdisplay_t display)
1502{
1503    BDBG_OBJECT_ASSERT(display, bdisplay);
1504
1505    if (display->audioDac.handle) {
1506        NEXUS_AudioOutput_RemoveAllInputs(NEXUS_AudioDac_GetConnector(display->audioDac.handle));
1507    }
1508
1509    if (display->nDisplay) {
1510        NEXUS_Display_RemoveAllOutputs(display->nDisplay);
1511        NEXUS_Display_Close(display->nDisplay);
1512        display->nDisplay = NULL;
1513    }
1514    if (display->nAudioMixer) {
1515        NEXUS_AudioInput_Shutdown(NEXUS_AudioMixer_GetConnector(display->nAudioMixer));
1516        NEXUS_AudioMixer_Close(display->nAudioMixer);
1517        display->nAudioMixer = NULL;
1518    }
1519    BDBG_OBJECT_UNSET(display, bdisplay);
1520}
1521
1522void nexus2rect(bsettop_rect *settop_rect, const NEXUS_Rect *pRect)
1523{
1524    settop_rect->x = pRect->x;
1525    settop_rect->y = pRect->y;
1526    settop_rect->width = pRect->width;
1527    settop_rect->height = pRect->height;
1528}
1529
1530bresult bdecode_window_get(bdecode_window_t window, bdecode_window_settings *settings)
1531{
1532    NEXUS_VideoWindowSettings nWindowSettings;
1533    #if BCHP_CHIP == 3548 || BCHP_CHIP == 3556
1534    #else
1535     NEXUS_PictureCtrlCommonSettings nPictureCtrlCommonSettings;
1536    #endif
1537    #if B_N_DNR
1538    NEXUS_VideoWindowDnrSettings nDnrSettings;
1539    #endif
1540    #if B_HAS_ANR
1541     NEXUS_VideoWindowAnrSettings nAnrSettings;
1542    #endif
1543    BDBG_MSG(("bdecode_window_get"));
1544    window->settings.cloned = window->parent?1:0;
1545
1546    *settings = window->settings;
1547
1548    NEXUS_VideoWindow_GetSettings(window->nWindow, &nWindowSettings);
1549    nexus2rect(&settings->position, &nWindowSettings.position);
1550    nexus2rect(&settings->cliprect, &nWindowSettings.clipRect);
1551    settings->visible = nWindowSettings.visible;
1552    settings->box_detect = nWindowSettings.letterBoxDetect;
1553    #if BCHP_CHIP == 3548 || BCHP_CHIP == 3556
1554    #else
1555    NEXUS_PictureCtrl_GetCommonSettings(window->nWindow,&nPictureCtrlCommonSettings);
1556    settings->brightness = nPictureCtrlCommonSettings.brightness;
1557    settings->contrast = nPictureCtrlCommonSettings.contrast;
1558    settings->hue = nPictureCtrlCommonSettings.hue;
1559    settings->saturation = nPictureCtrlCommonSettings.saturation;
1560    settings->sharpness = nPictureCtrlCommonSettings.sharpness;
1561    #endif
1562
1563    #if B_N_DNR
1564    NEXUS_VideoWindow_GetDnrSettings(window->nWindow,&nDnrSettings);
1565   
1566    settings->dcr_level = bnexus_to_settop_pq_levels(((nDnrSettings.dcr.mode == NEXUS_VideoWindowFilterMode_eBypass)?
1567                                                     (int32_t)SETTOP_ANR_DNR_OFF_LEVEL:nDnrSettings.dcr.level),pq_dcr);
1568    settings->mnr_level = bnexus_to_settop_pq_levels(((nDnrSettings.mnr.mode == NEXUS_VideoWindowFilterMode_eBypass)?
1569                                                     (int32_t)SETTOP_ANR_DNR_OFF_LEVEL:nDnrSettings.mnr.level),pq_mnr);
1570    settings->bnr_level = bnexus_to_settop_pq_levels(((nDnrSettings.bnr.mode == NEXUS_VideoWindowFilterMode_eBypass)?
1571                                                     (int32_t)SETTOP_ANR_DNR_OFF_LEVEL:nDnrSettings.bnr.level),pq_bnr);
1572    #endif
1573
1574    #if B_HAS_ANR
1575    if (window == gWindowMadOwner)
1576    {
1577      NEXUS_VideoWindow_GetAnrSettings(window->nWindow, &nAnrSettings);
1578      settings->anr_level = bnexus_to_settop_pq_levels(((nAnrSettings.anr.mode == NEXUS_VideoWindowFilterMode_eBypass)?
1579                                                        (int32_t)SETTOP_ANR_DNR_OFF_LEVEL:nAnrSettings.anr.level),pq_anr);   
1580    }
1581    #endif
1582    return 0;
1583}
1584
1585void rect2nexus(NEXUS_Rect *pRect, const bsettop_rect *settop_rect)
1586{
1587    pRect->x = settop_rect->x;
1588    pRect->y = settop_rect->y;
1589    pRect->width = settop_rect->width;
1590    pRect->height = settop_rect->height;
1591}
1592
1593
1594
1595
1596
1597/* use this api to set biox detect on both main and clone windows in HDSD simul mode*/
1598static bresult bdecode_p_window_set_boxdetect(bdecode_window_t window,bool box_detect)
1599{
1600    NEXUS_Error rc=0;
1601    NEXUS_VideoWindowSettings nWindowSettings;
1602    bdecode_window_t parent=NULL;
1603    bdecode_window_t clone=NULL;
1604    if(window->clone)
1605    {
1606        clone=window->clone;
1607        parent=window;
1608    }
1609    else if(window->parent)
1610    {
1611        clone = window;
1612        parent=window->parent;
1613    }
1614    else
1615    {
1616        parent=window;
1617        clone=NULL;
1618    }
1619    if(clone )
1620    {
1621        NEXUS_VideoWindow_GetSettings(clone->nWindow, &nWindowSettings);
1622        nWindowSettings.letterBoxDetect = box_detect;
1623        nWindowSettings.letterBoxAutoCut = true;
1624        rc = NEXUS_VideoWindow_SetSettings(clone->nWindow, &nWindowSettings);
1625        if (rc){rc  = BSETTOP_ERROR(berr_external_error); return rc;}
1626        /* save applied box detect settings */
1627        clone->settings.box_detect=box_detect;
1628    }
1629    if(parent)
1630    {
1631        NEXUS_VideoWindow_GetSettings(parent->nWindow, &nWindowSettings);
1632        nWindowSettings.letterBoxDetect = box_detect;
1633        nWindowSettings.letterBoxAutoCut = true;
1634        rc = NEXUS_VideoWindow_SetSettings(parent->nWindow, &nWindowSettings);
1635        if (rc){rc  = BSETTOP_ERROR(berr_external_error); return rc;}
1636        /* save applied box detect settings */
1637        parent->settings.box_detect=box_detect;
1638    }
1639    return rc;
1640}
1641
1642/* set window contecnt mode according to setting in the correcponding displays */
1643static bresult bdecode_p_window_set_content_mode(bdecode_window_t window)
1644{
1645    NEXUS_Error rc=0;
1646    NEXUS_VideoWindowSettings nWindowSettings;
1647    bdecode_window_t parent=NULL;
1648    bdecode_window_t clone=NULL;
1649    if(window->clone)
1650    {
1651        clone=window->clone;
1652        parent=window;
1653    }
1654    else if(window->parent)
1655    {
1656        clone = window;
1657        parent=window->parent;
1658    }
1659    else
1660    {
1661        parent=window;
1662        clone=NULL;
1663    }
1664#if 0
1665    if(window->parent == NULL && parent && clone)
1666    {
1667        if (parent->display->settings.content_mode == bdisplay_content_mode_zoom || parent->display->settings.content_mode == bdisplay_content_mode_panscan  )
1668        {
1669            BDBG_WRN(("forcing %d content mode on SD display",parent->display->settings.content_mode));
1670            clone->display->settings.content_mode= parent->display->settings.content_mode;
1671        }
1672    }
1673#endif
1674    if(parent)
1675    {
1676        NEXUS_VideoWindow_GetSettings(parent->nWindow, &nWindowSettings);
1677        nWindowSettings.contentMode=parent->display->settings.content_mode;
1678        rc = NEXUS_VideoWindow_SetSettings(parent->nWindow, &nWindowSettings);
1679        if (rc){rc  = BSETTOP_ERROR(berr_external_error); return rc;}
1680    }
1681    if(clone )
1682    {
1683        NEXUS_VideoWindow_GetSettings(clone->nWindow, &nWindowSettings);
1684        nWindowSettings.contentMode=clone->display->settings.content_mode;
1685        rc = NEXUS_VideoWindow_SetSettings(clone->nWindow, &nWindowSettings);
1686        if (rc){rc  = BSETTOP_ERROR(berr_external_error); return rc;}
1687    }
1688    return rc;
1689}
1690/* force the content modes on windows for both displays */
1691static bresult bdecode_p_window_set_force_content_mode(bdecode_window_t window,bdisplay_content_mode content_mode)
1692{
1693    NEXUS_Error rc=0;
1694    NEXUS_VideoWindowSettings nWindowSettings;
1695    bdecode_window_t parent=NULL;
1696    bdecode_window_t clone=NULL;
1697    if(window->clone)
1698    {
1699        clone=window->clone;
1700        parent=window;
1701    }
1702    else if(window->parent)
1703    {
1704        clone = window;
1705        parent=window->parent;
1706    }
1707    else
1708    {
1709        parent=window;
1710        clone=NULL;
1711    }
1712    if(parent)
1713    {
1714        NEXUS_VideoWindow_GetSettings(parent->nWindow, &nWindowSettings);
1715        nWindowSettings.contentMode=content_mode;
1716        rc = NEXUS_VideoWindow_SetSettings(parent->nWindow, &nWindowSettings);
1717        if (rc){rc  = BSETTOP_ERROR(berr_external_error); return rc;}
1718    }
1719    if(clone )
1720    {
1721        NEXUS_VideoWindow_GetSettings(clone->nWindow, &nWindowSettings);
1722        nWindowSettings.contentMode=content_mode;
1723        rc = NEXUS_VideoWindow_SetSettings(clone->nWindow, &nWindowSettings);
1724        if (rc){rc  = BSETTOP_ERROR(berr_external_error); return rc;}
1725    }
1726    return rc;
1727}
1728
1729bresult bdecode_window_set(bdecode_window_t window, const bdecode_window_settings *settings)
1730{
1731    NEXUS_VideoWindowSettings nWindowSettings;
1732#if BCHP_CHIP == 3548 || BCHP_CHIP == 3556
1733#else
1734    NEXUS_PictureCtrlCommonSettings nPictureCtrlCommonSettings;
1735#endif
1736#if B_N_DNR
1737    NEXUS_VideoWindowDnrSettings nDnrSettings;
1738#endif
1739#if B_HAS_ANR
1740    NEXUS_VideoWindowAnrSettings nAnrSettings;
1741#endif
1742    NEXUS_VideoWindowMadSettings nMadSettings;
1743    NEXUS_Error rc=0;
1744
1745    BDBG_MSG(("bdecode_window_set window %p %d,%d,%d,%d",window,settings->position.x, settings->position.y, settings->position.width, settings->position.height));
1746
1747    /* switch to display manual mode */
1748    NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eManual);
1749
1750    NEXUS_VideoWindow_GetSettings(window->nWindow, &nWindowSettings);
1751    rect2nexus(&nWindowSettings.position, &settings->position);
1752    rect2nexus(&nWindowSettings.clipRect, &settings->cliprect);
1753    nWindowSettings.clipBase.x = 0;
1754    nWindowSettings.clipBase.y = 0;
1755    nWindowSettings.clipBase.width = settings->position.width;
1756    nWindowSettings.clipBase.height = settings->position.height;
1757    nWindowSettings.visible = settings->visible;
1758    /* nWindowSettings.zorder is set in bsettop_p_display_apply_zorder */
1759#if B_DECODE_CRC_CAPTURE
1760    nWindowSettings.forceCapture = true;
1761#endif
1762
1763    rc = NEXUS_VideoWindow_SetSettings(window->nWindow, &nWindowSettings);
1764    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1765
1766    rc = bdecode_p_window_set_boxdetect(window,settings->box_detect);
1767    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1768
1769#if B_DECODE_CRC_CAPTURE
1770#if BCHP_CHIP == 3548 || BCHP_CHIP == 3556
1771    {
1772    NEXUS_VideoWindowBandwidthEquationSettings settings;
1773    NEXUS_VideoWindow_GetBandwidthEquationSettings(window->nWindow, &settings);
1774    settings.delta = 1000000;
1775    settings.bias = NEXUS_ScalerCaptureBias_eScalerBeforeCapture;
1776    rc = NEXUS_VideoWindow_SetBandwidthEquationSettings(window->nWindow, &settings);
1777    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1778    }
1779#else
1780    {
1781    NEXUS_VideoWindowScalerSettings scalerSettings;
1782    NEXUS_VideoWindow_GetScalerSettings(window->nWindow, &scalerSettings);
1783    scalerSettings.bandwidthEquationParams.delta = 1000000;
1784    scalerSettings.bandwidthEquationParams.bias = NEXUS_ScalerCaptureBias_eScalerBeforeCapture;
1785    rc = NEXUS_VideoWindow_SetScalerSettings(window->nWindow, &scalerSettings);
1786    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1787    }
1788#endif
1789#endif
1790
1791    bsettop_p_display_zorder_set(window->display, window, settings->zorder);
1792
1793    if (b_window_is_full_screen(&window->display->settings, &settings->position) && settings->visible && window->decode)
1794    {
1795        BDBG_MSG(("Window is full screen set frame master %p",window));
1796        bdisplay_p_set_framerate_master(window->display, window->decode);
1797    }
1798
1799    if (b_window_is_full_screen(&window->display->settings, &settings->position) && settings->visible)
1800    {
1801        /* apply aspect ratio conversion to full-screen window and clone */
1802        rc = bdecode_p_window_set_content_mode(window);
1803        if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1804
1805    }
1806    else
1807    {
1808        /* don't apply aspect ratio conversion for scaled down windows */
1809        /* force content mode on this window and clone */
1810        rc = bdecode_p_window_set_force_content_mode(window,NEXUS_VideoWindowContentMode_eFull);
1811        if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1812    }
1813
1814#if BCHP_CHIP != 7420
1815    /* we have one MAD, make sure we give it to bigger window */
1816    if(settings->deinterlacer && settings->visible )
1817    {
1818        if(gWindowMadOwner == NULL )
1819        {
1820            NEXUS_VideoWindow_GetMadSettings(window->nWindow,&nMadSettings);
1821            nMadSettings.deinterlace = true;
1822            nMadSettings.enable32Pulldown = true;
1823            nMadSettings.enable22Pulldown = true;
1824            nMadSettings.gameMode = window->playbackDeinterlacer ? NEXUS_VideoWindowGameMode_e5Fields_ForceSpatial : NEXUS_VideoWindowGameMode_eOff;
1825            rc = NEXUS_VideoWindow_SetMadSettings(window->nWindow,&nMadSettings);
1826            if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1827            gWindowMadOwner = window;
1828            BDBG_MSG(("Mad enabled on window %p",window->nWindow));
1829
1830        }
1831        else if(gWindowMadOwner != window && settings->position.height >=  gWindowMadOwner->settings.position.height)
1832        {
1833            BDBG_MSG(("Mad disabled on window %p enabled on window%p",gWindowMadOwner->nWindow,window->nWindow));
1834            NEXUS_VideoWindow_GetMadSettings(gWindowMadOwner->nWindow,&nMadSettings);
1835            nMadSettings.deinterlace = false;
1836            nMadSettings.enable32Pulldown = false;
1837            nMadSettings.enable22Pulldown = false;
1838            rc = NEXUS_VideoWindow_SetMadSettings(gWindowMadOwner->nWindow,&nMadSettings);
1839            if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1840                        rc = NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eNow);
1841                        if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1842
1843            NEXUS_VideoWindow_GetMadSettings(window->nWindow,&nMadSettings);
1844            nMadSettings.deinterlace = true;
1845            nMadSettings.enable32Pulldown = true;
1846            nMadSettings.enable22Pulldown = true;
1847            nMadSettings.gameMode = window->playbackDeinterlacer ? NEXUS_VideoWindowGameMode_e5Fields_ForceSpatial : NEXUS_VideoWindowGameMode_eOff;
1848            rc = NEXUS_VideoWindow_SetMadSettings(window->nWindow,&nMadSettings);
1849            if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1850            gWindowMadOwner = window;
1851        }
1852    }
1853    else if(gWindowMadOwner == window)
1854    {
1855        NEXUS_VideoWindow_GetMadSettings(window->nWindow,&nMadSettings);
1856        nMadSettings.deinterlace = false;
1857        rc = NEXUS_VideoWindow_SetMadSettings(window->nWindow,&nMadSettings);
1858        if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1859        BDBG_MSG(("Mad disabled on window %p",window->nWindow));
1860        gWindowMadOwner = NULL;
1861    }
1862#else
1863    /* Apply settings only to the main window of the main display */
1864    if (window == gWindowMadOwner)
1865    {
1866        if(settings->deinterlacer && !window->playbackDeinterlacer )
1867        {
1868            NEXUS_VideoWindow_GetMadSettings(window->nWindow,&nMadSettings);
1869            nMadSettings.deinterlace = true;
1870            rc = NEXUS_VideoWindow_SetMadSettings(window->nWindow,&nMadSettings);
1871            if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1872            BDBG_MSG(("Mad enabled on window %p",window->nWindow));
1873        }
1874        else
1875        {
1876            NEXUS_VideoWindow_GetMadSettings(window->nWindow,&nMadSettings);
1877            nMadSettings.deinterlace = false;
1878            rc = NEXUS_VideoWindow_SetMadSettings(window->nWindow,&nMadSettings);
1879            if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1880            BDBG_MSG(("Mad disabled on window %p",window->nWindow));
1881        }
1882    }
1883#endif
1884
1885    /**
1886    * DNR
1887    **/
1888#if B_N_DNR
1889#if B_HAS_LEGACY_VDC
1890    if(!window->settings.cloned){
1891      NEXUS_VideoWindow_GetDnrSettings(window->nWindow,&nDnrSettings);
1892      nDnrSettings.bnr.level = settings->bnr_level;
1893      nDnrSettings.dcr.level = settings->dcr_level;
1894      nDnrSettings.mnr.level = settings->mnr_level;
1895      rc = NEXUS_VideoWindow_SetDnrSettings(window->nWindow, &nDnrSettings);
1896      if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1897    }
1898#else
1899    NEXUS_VideoWindow_GetDnrSettings(window->nWindow,&nDnrSettings);
1900    BDBG_MSG(("-> DNR Settings: %d bnr_level[settings->bnr_level] %d  nDnrSettings.bnr.mode  %d nDnrSettings.bnr.level %d",settings->bnr_level,bnr_level[settings->bnr_level], nDnrSettings.bnr.mode,nDnrSettings.bnr.level));
1901    BDBG_MSG(("-> DNR Settings: %d dcr_level[settings->dcr_level] %d  nDnrSettings.dcr.mode  %d nDnrSettings.dcr.level %d",settings->dcr_level,dcr_level[settings->dcr_level], nDnrSettings.dcr.mode,nDnrSettings.dcr.level));
1902    BDBG_MSG(("-> DNR Settings: %d mnr_level[settings->mnr_level]%d  nDnrSettings.mnr.mode  %d nDnrSettings.mnr.level %d",settings->mnr_level,mnr_level[settings->mnr_level], nDnrSettings.mnr.mode,nDnrSettings.mnr.level));
1903
1904    if( nDnrSettings.bnr.level != bnr_level[settings->bnr_level]
1905        ||  nDnrSettings.dcr.level != dcr_level[settings->dcr_level]
1906        || nDnrSettings.mnr.level != mnr_level[settings->mnr_level] )
1907     {
1908       nDnrSettings.bnr.mode = NEXUS_VideoWindowFilterMode_eBypass;
1909       nDnrSettings.dcr.mode = NEXUS_VideoWindowFilterMode_eBypass;
1910       nDnrSettings.mnr.mode = NEXUS_VideoWindowFilterMode_eBypass;
1911
1912       if(settings->bnr_level != bwindow_dnr_level_off)
1913          nDnrSettings.bnr.mode = NEXUS_VideoWindowFilterMode_eEnable;
1914       nDnrSettings.bnr.level = bnr_level[settings->bnr_level];
1915
1916      if(settings->dcr_level != bwindow_dnr_level_off)
1917        nDnrSettings.dcr.mode = NEXUS_VideoWindowFilterMode_eEnable;
1918      nDnrSettings.dcr.level = dcr_level[settings->dcr_level];
1919
1920      if(settings->mnr_level != bwindow_dnr_level_off)
1921        nDnrSettings.mnr.mode = NEXUS_VideoWindowFilterMode_eEnable;
1922      nDnrSettings.mnr.level = mnr_level[settings->mnr_level];
1923
1924      rc = NEXUS_VideoWindow_SetDnrSettings(window->nWindow, &nDnrSettings);
1925      if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1926      BDBG_MSG(("<- DNR Settings:  nDnrSettings.bnr.mode  %d nDnrSettings.bnr.level %d",  nDnrSettings.bnr.mode,nDnrSettings.bnr.level));
1927      BDBG_MSG(("<- DNR Settings:  nDnrSettings.dcr.mode  %d nDnrSettings.dcr.level %d", nDnrSettings.dcr.mode,nDnrSettings.dcr.level));
1928      BDBG_MSG(("<- DNR Settings:  nDnrSettings.mnr.mode  %d nDnrSettings.mnr.level %d", nDnrSettings.mnr.mode,nDnrSettings.mnr.level));
1929    }
1930#endif
1931#endif
1932
1933#if B_HAS_ANR
1934    /**
1935    * ANR
1936    **/
1937    if (window == gWindowMadOwner)
1938    {
1939        NEXUS_VideoWindow_GetAnrSettings(window->nWindow, &nAnrSettings);
1940        BDBG_MSG(("-> ANR Settings: %d anr_level[settings->anr_level] %d nAnrSettings.anr.mode  %d  nAnrSettings.anr.level %d",settings->anr_level,anr_level[settings->anr_level],nAnrSettings.anr.mode, nAnrSettings.anr.level));
1941        if(nAnrSettings.anr.level != anr_level[settings->anr_level])
1942        {
1943          nAnrSettings.anr.mode = NEXUS_VideoWindowFilterMode_eBypass;
1944          if(settings->anr_level != bwindow_dnr_level_off)
1945            nAnrSettings.anr.mode = NEXUS_VideoWindowFilterMode_eEnable;
1946          nAnrSettings.anr.level = anr_level[settings->anr_level];
1947          rc = NEXUS_VideoWindow_SetAnrSettings(window->nWindow, &nAnrSettings);
1948          if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1949          BDBG_MSG(("<- ANR Settings: nAnrSettings.anr.mode  %d  nAnrSettings.anr.level %d",nAnrSettings.anr.mode, nAnrSettings.anr.level));
1950        }
1951    }
1952#endif
1953
1954#if BCHP_CHIP == 3548 || BCHP_CHIP == 3556
1955     rc = NEXUS_VideoWindow_SetBrightness(window->nWindow, settings->brightness);
1956     if (rc) {rc = BSETTOP_ERROR(berr_external_error); goto error;}
1957
1958     rc = NEXUS_VideoWindow_SetContrast(window->nWindow, settings->contrast);
1959     if (rc) {rc = BSETTOP_ERROR(berr_external_error); goto error;}
1960
1961     rc = NEXUS_VideoWindow_SetHue(window->nWindow, settings->hue);
1962     if (rc) {rc = BSETTOP_ERROR(berr_external_error); goto error;}
1963
1964     rc = NEXUS_VideoWindow_SetSaturation(window->nWindow, settings->saturation);
1965     if (rc) {rc = BSETTOP_ERROR(berr_external_error); goto error;}
1966
1967     rc = NEXUS_VideoWindow_SetSharpness(window->nWindow, settings->sharpness ? true : false, settings->sharpness);
1968     if (rc) {rc = BSETTOP_ERROR(berr_external_error); goto error;}
1969#else
1970    NEXUS_PictureCtrl_GetCommonSettings(window->nWindow,&nPictureCtrlCommonSettings);
1971    nPictureCtrlCommonSettings.brightness = settings->brightness;
1972    nPictureCtrlCommonSettings.contrast = settings->contrast;
1973    nPictureCtrlCommonSettings.hue = settings->hue;
1974    nPictureCtrlCommonSettings.saturation = settings->saturation;
1975    nPictureCtrlCommonSettings.sharpness = settings->sharpness;
1976    nPictureCtrlCommonSettings.sharpnessEnable = 1;/* settings->sharpness?1:0; */
1977    rc =NEXUS_PictureCtrl_SetCommonSettings(window->nWindow,&nPictureCtrlCommonSettings);
1978    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1979#if BCHP_CHIP == 7400 || BCHP_CHIP == 7420 || BCHP_CHIP == 7325 || BCHP_CHIP == 7335 || BCHP_CHIP==7340 || BCHP_CHIP==7342 \
1980        || BCHP_CHIP ==7125 || BCHP_CHIP ==7468
1981{
1982    NEXUS_PictureCtrlAdvColorSettings nPictureAdvSettings;
1983    /* coverity[stack_use_local_overflow] */
1984        NEXUS_PictureCtrlContrastStretch contrastStretchSettings;
1985
1986    NEXUS_PictureCtrl_GetAdvColorSettings(window->nWindow,&nPictureAdvSettings);
1987    nPictureAdvSettings.fleshTone = settings->auto_flesh_tone;
1988    nPictureAdvSettings.blueBoost = settings->blue_stretch;
1989    nPictureAdvSettings.greenBoost = settings->green_stretch;
1990    rc = NEXUS_PictureCtrl_SetAdvColorSettings(window->nWindow,&nPictureAdvSettings);
1991    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
1992    /* settings->display_rate_master; */
1993
1994    NEXUS_PictureCtrl_GetContrastStretch(window->nWindow, &contrastStretchSettings);
1995    contrastStretchSettings.gain = settings->dynamic_contrast;
1996    contrastStretchSettings.gainShift = 8;
1997    contrastStretchSettings.enabled = true;
1998    rc = NEXUS_PictureCtrl_SetContrastStretch(window->nWindow, &contrastStretchSettings);
1999    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
2000}
2001#endif
2002#endif
2003
2004{
2005    NEXUS_VideoWindowSplitScreenSettings splitScreen;
2006    NEXUS_VideoWindow_GetSplitScreenSettings(window->nWindow, &splitScreen);
2007
2008    splitScreen.hue = settings->splitscreen_mode;
2009    splitScreen.contrast = settings->splitscreen_mode;
2010    splitScreen.brightness = settings->splitscreen_mode;
2011    splitScreen.colorTemp = settings->splitscreen_mode;
2012    splitScreen.sharpness = settings->splitscreen_mode;
2013    splitScreen.contrastStretch = settings->splitscreen_mode;
2014    splitScreen.dnr = settings->splitscreen_mode;
2015    splitScreen.anr = settings->splitscreen_mode;
2016    splitScreen.autoFlesh = settings->splitscreen_mode;
2017    splitScreen.blueBoost = settings->splitscreen_mode;
2018    splitScreen.greenBoost = settings->splitscreen_mode;
2019    splitScreen.blueStretch = settings->splitscreen_mode;
2020    splitScreen.dejagging = settings->splitscreen_mode;
2021    splitScreen.deringing = settings->splitscreen_mode;
2022
2023    NEXUS_VideoWindow_SetSplitScreenSettings(window->nWindow, &splitScreen);
2024}
2025
2026    window->settings = *settings;
2027    rc = NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eNow);
2028    if (rc){rc  = BSETTOP_ERROR(berr_external_error); goto error;}
2029error:
2030    /* switch back to auto mode and apply the settings */
2031    NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eAuto);
2032    return rc;
2033
2034}
2035
2036bresult bdecode_p_window_set_no_delay( bdecode_window_t window, bool noDelay ) {
2037
2038    bdecode_window_settings settings;
2039    NEXUS_Error rc=0;
2040
2041    bdecode_window_get(window, &settings);
2042    if ( noDelay ) {
2043        if ( settings.deinterlacer ) {
2044            /* Turn it off */
2045            BDBG_MSG(("Turning de-interlacer OFF in playback pause"));
2046            window->playbackDeinterlacer = true;
2047            rc = bdecode_window_set(window, &settings);
2048        }
2049    }
2050    else {
2051        /* Restore old setting */
2052        if( settings.deinterlacer ) {
2053            BDBG_MSG(("Turning de-interlacer ON in normal play"));
2054            window->playbackDeinterlacer = false;
2055            rc = bdecode_window_set(window, &settings);
2056        }
2057    }
2058    return rc;
2059}
2060
2061bresult boutput_rf_set(boutput_rf_t rf, const boutput_rf_settings *settings)
2062{
2063    rf->desired = *settings;
2064    return 0;
2065}
2066
2067static bool b_is_hd(bvideo_format video_format)
2068{
2069    bvideo_format_settings format_settings;
2070    bvideo_get_format_settings(video_format, &format_settings);
2071    return (format_settings.height > 576) || !format_settings.interlaced;
2072}
2073
2074void
2075bdisplay_get(bdisplay_t display, bdisplay_settings *settings)
2076{
2077    BDBG_OBJECT_ASSERT(display, bdisplay);
2078    *settings = display->settings;
2079}
2080
2081bresult
2082bdisplay_set(bdisplay_t display, const bdisplay_settings *settings)
2083{
2084    NEXUS_DisplaySettings nSettings;
2085    NEXUS_ComponentOutputSettings nComponentOutputSettings;
2086#if B_N_DVI_OUTPUTS
2087    NEXUS_HdmiOutputSettings nHdmiOutputSettings;
2088    NEXUS_HdmiOutputStatus nHdmiOutputStatus;
2089#endif
2090    NEXUS_Error rc;
2091    bresult result = b_ok;
2092
2093#if B_N_RF_OUTPUTS > 0
2094    bool change_rf =
2095        settings->rf != display->settings.rf ||
2096        (settings->rf &&
2097         BKNI_Memcmp(&settings->rf->cfg, &settings->rf->desired,
2098            sizeof(settings->rf->cfg)));
2099#endif
2100#if B_N_DVI_OUTPUTS > 0
2101    bool change_dvi =
2102        settings->dvi != display->settings.dvi ||
2103        (settings->dvi && !settings->dvi->connected) ||
2104        settings->aspect_ratio != display->settings.aspect_ratio ||
2105        (settings->dvi &&
2106         BKNI_Memcmp(&settings->dvi->cfg, &settings->dvi->desired,
2107            sizeof(settings->dvi->cfg)));
2108#endif
2109
2110#if B_N_SPDIF_OUTPUTS > 0
2111    bool change_spdif =
2112        display->settings.spdif != settings->spdif ||
2113        (settings->spdif &&
2114        BKNI_Memcmp(&settings->spdif->cfg, &settings->spdif->desired,
2115            sizeof(settings->spdif->cfg)));
2116#endif
2117
2118    BDBG_OBJECT_ASSERT(display, bdisplay);
2119
2120    /* must remove before changing format, otherwise nexus will auto-remove */
2121    if (settings->composite != display->settings.composite) {
2122        if (display->settings.composite) {
2123            rc = NEXUS_Display_RemoveOutput(display->nDisplay, NEXUS_CompositeOutput_GetConnector(display->settings.composite->handle));
2124            if (rc) BSETTOP_ERROR(berr_external_error); /* keep going */
2125        }
2126    }
2127
2128    if ( settings->svideo != display->settings.svideo )
2129    {
2130        if (display->settings.svideo) {
2131            rc = NEXUS_Display_RemoveOutput(display->nDisplay, NEXUS_SvideoOutput_GetConnector(display->settings.svideo->handle));
2132            if (rc) BSETTOP_ERROR(berr_external_error); /* keep going */
2133        }
2134    }
2135
2136    if (settings->component != display->settings.component) {
2137        if (display->settings.component) {
2138            rc = NEXUS_Display_RemoveOutput(display->nDisplay, display->settings.component->videoOutput);
2139            if (rc) BSETTOP_ERROR(berr_external_error); /* keep going */
2140        }
2141    }
2142#if B_N_RF_OUTPUTS
2143    if (settings->rf != display->settings.rf) {
2144        if (display->settings.rf) {
2145            rc = NEXUS_Display_RemoveOutput(display->nDisplay, NEXUS_Rfm_GetVideoConnector(display->settings.rf->handle));
2146            if (rc) {rc = BSETTOP_ERROR(berr_external_error);}
2147
2148            b_set_rfm_audio_source(display->settings.rf, NULL);
2149        }
2150    }
2151#endif
2152
2153    if (!is_panel_output()) {
2154        NEXUS_VideoFormatInfo videoFormatInfo;
2155        NEXUS_VideoFormat format = b_displayformat2nexus(settings->format, &settings->vesa_settings);
2156        NEXUS_VideoFormat prevFormat;
2157
2158#if B_N_DVI_OUTPUTS
2159    /* DVI_VALIDATE_EDID_FORMAT=1 */
2160    if (settings->dvi && settings->dvi->desired.validate_edid_format) {
2161        if ( settings->dvi->connected && settings->dvi->handle) {
2162            rc = NEXUS_HdmiOutput_GetStatus(settings->dvi->handle, &nHdmiOutputStatus);
2163            if (rc) return BSETTOP_ERROR(berr_external_error);
2164
2165            if (!nHdmiOutputStatus.videoFormatSupported[format]) {
2166                BDBG_ERR(("Attached HDMI receiver does not support the requested format"));
2167                return BSETTOP_ERROR(berr_not_supported);
2168            }
2169        }
2170    }
2171#endif
2172        NEXUS_Display_GetSettings(display->nDisplay, &nSettings);
2173        prevFormat = nSettings.format;
2174        nSettings.format = format;
2175        /* for HD, force to 16x9. Nexus allows for 4x3 HD, but settop api does not. */
2176        if (b_is_hd(settings->format)) {
2177            nSettings.aspectRatio = NEXUS_DisplayAspectRatio_e16x9;
2178        }
2179        else {
2180        nSettings.aspectRatio = b_displayaspectratio2nexus(settings->aspect_ratio);
2181        }
2182        nSettings.background = settings->background_color;
2183        rc = NEXUS_Display_SetSettings(display->nDisplay, &nSettings);
2184        if (rc) return BSETTOP_ERROR(berr_external_error);
2185
2186        if (prevFormat != nSettings.format && display->graphics) {
2187            bgraphics_settings graphics_settings;
2188
2189            NEXUS_VideoFormat_GetInfo(format, &videoFormatInfo);
2190            bgraphics_get(display->graphics, &graphics_settings);
2191            graphics_settings.destination_height = videoFormatInfo.height;
2192            graphics_settings.destination_width = videoFormatInfo.width;
2193            result = bgraphics_set(display->graphics, &graphics_settings);
2194            if (result) return result;
2195        }
2196    }
2197
2198    if (settings->content_mode != display->settings.content_mode) {
2199        /* only apply content mode to main window. PIP should stay Full */
2200        NEXUS_VideoWindowHandle nWindow = display->window[0].nWindow;
2201        if (nWindow) {
2202            NEXUS_VideoWindowSettings nWindowSettings;
2203            BDBG_CASSERT(bdisplay_content_mode_full_nonlinear == NEXUS_VideoWindowContentMode_eFullNonLinear);
2204
2205            NEXUS_VideoWindow_GetSettings(nWindow, &nWindowSettings);
2206            nWindowSettings.contentMode = settings->content_mode;
2207            rc = NEXUS_VideoWindow_SetSettings(nWindow, &nWindowSettings);
2208            if (rc) return BSETTOP_ERROR(berr_external_error);
2209
2210        }
2211    }
2212
2213    if (settings->composite != display->settings.composite) {
2214        if (settings->composite) {
2215            rc = NEXUS_Display_AddOutput(display->nDisplay, NEXUS_CompositeOutput_GetConnector(settings->composite->handle));
2216            if (rc) return BSETTOP_ERROR(berr_external_error);
2217        }
2218    }
2219
2220    if (settings->composite2 != display->settings.composite2) {
2221        if (settings->composite2) {
2222            rc = NEXUS_Display_AddOutput(display->nDisplay, NEXUS_CompositeOutput_GetConnector(settings->composite2->handle));
2223            if (rc) return BSETTOP_ERROR(berr_external_error);
2224        }
2225    }
2226    if (settings->svideo != display->settings.svideo) {
2227        if (settings->svideo) {
2228            rc = NEXUS_Display_AddOutput(display->nDisplay, NEXUS_SvideoOutput_GetConnector(settings->svideo->handle));
2229            if (rc) return BSETTOP_ERROR(berr_external_error);
2230        }
2231    }
2232    if (settings->component != display->settings.component) {
2233        if (settings->component) {
2234            rc = NEXUS_Display_AddOutput(display->nDisplay, settings->component->videoOutput);
2235            if (rc) return BSETTOP_ERROR(berr_external_error);
2236        }
2237    }
2238#if B_N_RF_OUTPUTS
2239    if (settings->rf && change_rf) {
2240        NEXUS_RfmSettings rfmSettings;
2241
2242        BDBG_MSG(("setting rf"));
2243        NEXUS_Rfm_GetSettings(settings->rf->handle, &rfmSettings);
2244        rfmSettings.channel = settings->rf->desired.channel;
2245        /* settings.country is ignored. Nexus RFM follows the format of the SD VEC. */
2246        rc = NEXUS_Rfm_SetSettings(settings->rf->handle, &rfmSettings);
2247        if (rc) return BSETTOP_ERROR(berr_external_error);
2248
2249        if (!display->settings.rf) {
2250            int i;
2251            bdisplay_t audio_display = display;
2252
2253            rc = NEXUS_Display_AddOutput(display->nDisplay, NEXUS_Rfm_GetVideoConnector(settings->rf->handle));
2254            if (rc) return BSETTOP_ERROR(berr_external_error);
2255
2256            /* Look for a cloned window */
2257            for ( i = 0; i < B_N_WINDOWS; i++ )
2258            {
2259                if ( display->window[i].parent )
2260                {
2261                    audio_display = display->window[i].parent->display;
2262                    break;
2263                }
2264            }
2265
2266            rc = b_set_rfm_audio_source(settings->rf, audio_display);
2267            if (rc) return BSETTOP_ERROR(berr_external_error);
2268        }
2269        /* the NEXUS_Display_RemoveOutput code is before any possible display format change */
2270    }
2271#endif
2272
2273
2274#if B_N_DVI_OUTPUTS
2275/* Format Changes must be done to Display not HDMI */
2276     if (change_dvi)
2277     {
2278        BDBG_MSG(("changing hdmi %p %d",settings->dvi, settings->dvi?settings->dvi->connected:false));
2279        if ( settings->dvi && !settings->dvi->connected )
2280        {
2281            NEXUS_HdmiOutputStatus nHdmiStatus;
2282            NEXUS_HdmiOutput_GetStatus(settings->dvi->handle, &nHdmiStatus);
2283            if ( nHdmiStatus.connected )
2284            {
2285                /* Attaching HDMI */
2286                BDBG_MSG(("Attaching HDMI"));
2287                settings->dvi->display = display;
2288                bdisplay_p_connect_hdmi(display, settings->dvi);
2289            }
2290            else
2291            {
2292                BDBG_MSG(("hdmi not connected"));
2293            }
2294        }
2295        else if ( display->settings.dvi && !settings->dvi && display->settings.dvi->connected )
2296        {
2297            /* Removing HDMI */
2298            BDBG_MSG(("Detaching HDMI"));
2299            bdisplay_p_disconnect_hdmi(display, display->settings.dvi);
2300        }
2301        if ( settings->dvi && settings->dvi->connected )
2302        {
2303            BDBG_MSG(("HDMI Settings Changed"));
2304            /* Settings Changed */
2305            if ( settings->dvi->desired.hdmi_audio_mode != settings->dvi->cfg.hdmi_audio_mode
2306#if B_HAS_DTS_ENCODE || B_HAS_AC3_ENCODE
2307                 || settings->dvi->desired.compressed_audio_format != settings->dvi->cfg.compressed_audio_format
2308#endif
2309                )
2310            {
2311                /* Audio mode change */
2312                bdisplay_p_enable_audio(display, false);
2313                NEXUS_AudioOutput_RemoveAllInputs(NEXUS_HdmiOutput_GetAudioConnector(settings->dvi->handle));
2314
2315                if ( settings->dvi->desired.hdmi_audio_mode == boutput_hdmi_audio_mode_pcm )
2316                {
2317                    BDBG_MSG(("Attaching HDMI to mixer"));
2318                    NEXUS_AudioOutput_AddInput(NEXUS_HdmiOutput_GetAudioConnector(settings->dvi->handle),
2319                                               NEXUS_AudioMixer_GetConnector(display->nAudioMixer));
2320                }
2321                else
2322                {
2323                    BDBG_MSG(("HDMI audio not attached to mixer,audio cound be compressed or multichannel %d",settings->dvi->desired.hdmi_audio_mode));
2324                }
2325                bdisplay_p_enable_audio(display, true);
2326            }
2327
2328            settings->dvi->cfg = settings->dvi->desired;
2329        }
2330     }
2331#endif /* B_N_DVI_OUTPUTS */
2332
2333
2334#if B_N_SPDIF_OUTPUTS
2335    if ( change_spdif )
2336    {
2337        BDBG_MSG(("changing spdif"));
2338        /* IMPORTANT: Do not bail out while this is diabled! */
2339        bdisplay_p_enable_audio(display, false);
2340        rc = 0;
2341        if ( display->settings.spdif )
2342        {
2343            /* Remove SPDIF from any existing connection */
2344            NEXUS_AudioOutput_RemoveAllInputs(NEXUS_SpdifOutput_GetConnector(display->settings.spdif->handle));
2345            display->settings.spdif->display = NULL;
2346           
2347            if ( settings->spdif )
2348            {
2349                /* Add to mixer only if set to PCM mode -- otherwise enabling audio will make the compressed connection */
2350                if ( settings->spdif->desired.pcm )
2351                {
2352                    rc = NEXUS_AudioOutput_AddInput(NEXUS_SpdifOutput_GetConnector(settings->spdif->handle),
2353                                                    NEXUS_AudioMixer_GetConnector(display->nAudioMixer));
2354                }
2355                settings->spdif->cfg = settings->spdif->desired;
2356                display->settings.spdif->display = display;
2357            }
2358            bdisplay_p_enable_audio(display, true);
2359            if ( rc ) return BSETTOP_ERROR(berr_external_error);
2360        }
2361    }
2362#endif
2363    if(settings->component && settings->component->handle)
2364    {
2365        NEXUS_ComponentOutput_GetSettings(settings->component->handle,&nComponentOutputSettings);
2366        nComponentOutputSettings.mpaaDecimationEnabled = settings->mpaa_enabled;
2367        nComponentOutputSettings.type = settings->component->desired.type == boutput_component_type_rgb ? NEXUS_ComponentOutputType_eRGB : NEXUS_ComponentOutputType_eYPrPb;
2368        rc = NEXUS_ComponentOutput_SetSettings(settings->component->handle,&nComponentOutputSettings);
2369        if ( rc ) return BSETTOP_ERROR(berr_external_error);
2370    }
2371#if B_N_DVI_OUTPUTS
2372    if(settings->dvi)
2373    {
2374        NEXUS_HdmiOutput_GetSettings(settings->dvi->handle,&nHdmiOutputSettings);
2375        nHdmiOutputSettings.mpaaDecimationEnabled = settings->mpaa_enabled;
2376        if (settings->component) {
2377            nHdmiOutputSettings.autoColorSpace = false;
2378            nHdmiOutputSettings.colorSpace = settings->component->desired.type == boutput_component_type_rgb ? NEXUS_ColorSpace_eRgb : NEXUS_ColorSpace_eYCbCr444;
2379        }
2380        else {
2381            nHdmiOutputSettings.autoColorSpace = true;
2382        }
2383        rc = NEXUS_HdmiOutput_SetSettings(settings->dvi->handle,&nHdmiOutputSettings);
2384        if ( rc ) return BSETTOP_ERROR(berr_external_error);
2385    }
2386#endif
2387
2388#if MACROVISION_SUPPORT
2389    if(display->settings.macrovision_type != settings->macrovision_type)
2390    {
2391        NEXUS_DisplayVbiSettings nDisplayVbiSettings;
2392        if(settings->macrovision_type == bmacrovision_type_custom && settings->macrovision_tables)
2393        {
2394            rc = NEXUS_Display_SetMacrovision(display->nDisplay,settings->macrovision_type,(NEXUS_DisplayMacrovisionTables*)&settings->macrovision_tables);
2395            if ( rc ) BSETTOP_ERROR(berr_external_error);
2396        }
2397        else
2398        {
2399            rc = NEXUS_Display_SetMacrovision(display->nDisplay,settings->macrovision_type,NULL);
2400            if ( rc ) BSETTOP_ERROR(berr_external_error);
2401        }
2402        NEXUS_Display_GetVbiSettings(display->nDisplay,&nDisplayVbiSettings);
2403        nDisplayVbiSettings.macrovisionEnabled =  (settings->macrovision_type==bmacrovision_type_none)?0:1;
2404        rc = NEXUS_Display_SetVbiSettings(display->nDisplay,&nDisplayVbiSettings);
2405        if ( rc ) BSETTOP_ERROR(berr_external_error);
2406    }
2407#endif
2408
2409#if DCS_SUPPORT
2410    if(settings->dcs_type != display->settings.dcs_type)
2411    {
2412        NEXUS_DisplayVbiSettings nDisplayVbiSettings;
2413        rc = NEXUS_Display_SetDcs(display->nDisplay,settings->dcs_type);
2414        if ( rc ) BSETTOP_ERROR(berr_external_error);
2415
2416        NEXUS_Display_GetVbiSettings(display->nDisplay,&nDisplayVbiSettings);
2417        nDisplayVbiSettings.dcsEnabled =  (settings->dcs_type==bdcs_type_dcs_off)?0:1;
2418        rc = NEXUS_Display_SetVbiSettings(display->nDisplay,&nDisplayVbiSettings);
2419        if ( rc ) BSETTOP_ERROR(berr_external_error);
2420    }
2421#endif
2422
2423    display->settings = *settings;
2424    /* Potentially refresh HDMI volume */
2425    if ( display->settings.spdif )
2426    {
2427        boutput_spdif_set_audio_volume(display->settings.spdif, &display->settings.spdif->volume);
2428    }
2429    return 0;
2430}
2431
2432void boutput_rf_get(boutput_rf_t rf, boutput_rf_settings *settings)
2433{
2434    *settings = rf->desired;
2435}
2436
2437bresult boutput_hdmi_set(boutput_hdmi_t hdmi, const boutput_hdmi_settings *settings)
2438{
2439#if B_N_DVI_OUTPUTS
2440    NEXUS_Error errCode;
2441    bvideo_format preferredFormat;
2442
2443    /* Don't overwrite preferred format */
2444    preferredFormat = hdmi->desired.edid_preferred_format;
2445
2446    hdmi->desired = *settings;
2447    hdmi->desired.edid_preferred_format = preferredFormat;
2448
2449#if NEXUS_HAS_SECURITY
2450    if ( settings->hdcp )
2451    {
2452        NEXUS_HdmiOutputHdcpStatus hdcpStatus;
2453        NEXUS_HdmiOutput_GetHdcpStatus(hdmi->handle, &hdcpStatus);
2454
2455        /* Re-authenticate if link is not yet authenticated */
2456        if (!hdcpStatus.transmittingEncrypted)
2457        {
2458            NEXUS_HdmiOutputHdcpSettings *pHdcpSettings;
2459            pHdcpSettings = BKNI_Malloc(sizeof(*pHdcpSettings));
2460            NEXUS_HdmiOutput_GetHdcpSettings(hdmi->handle, pHdcpSettings);
2461            if ( pHdcpSettings )
2462            {
2463                pHdcpSettings->pjCheckEnabled = settings->hdcp_pj_checking_enable;
2464                errCode = NEXUS_HdmiOutput_SetHdcpSettings(hdmi->handle, pHdcpSettings);
2465                BKNI_Free(pHdcpSettings);
2466                if ( errCode )
2467                {
2468                    return BSETTOP_ERROR(berr_external_error);
2469                }
2470                /* Start HDCP if connected */
2471                if ( hdmi->connected )
2472                {
2473                    errCode = NEXUS_HdmiOutput_StartHdcpAuthentication(hdmi->handle);
2474                    if ( errCode )
2475                    {
2476                        return BSETTOP_ERROR(berr_external_error);
2477                    }
2478                }
2479            }
2480            else
2481            {
2482                return BSETTOP_ERROR(berr_external_error);
2483            }
2484        }
2485    }
2486    else
2487    {
2488        errCode = NEXUS_HdmiOutput_DisableHdcpAuthentication(hdmi->handle);
2489        if ( errCode )
2490        {
2491            return BSETTOP_ERROR(berr_external_error);
2492        }
2493    }
2494#endif
2495
2496    /* Check for audio settings change */
2497    if ( settings->audio_delay != hdmi->cfg.audio_delay )
2498    {
2499        NEXUS_AudioOutputSettings audioSettings;
2500        NEXUS_AudioOutput audioOutput;
2501
2502        audioOutput = NEXUS_HdmiOutput_GetAudioConnector(hdmi->handle);
2503        NEXUS_AudioOutput_GetSettings(audioOutput, &audioSettings);
2504        audioSettings.additionalDelay = settings->audio_delay;
2505        errCode = NEXUS_AudioOutput_SetSettings(audioOutput, &audioSettings);
2506        if ( errCode )
2507        {
2508            return BSETTOP_ERROR(berr_external_error);
2509        }
2510    }
2511
2512    if ( settings->preemphasis_support != hdmi->cfg.preemphasis_support ||
2513         settings->hdmi_avmute_delay_pre_format_change != hdmi->cfg.hdmi_avmute_delay_pre_format_change ||
2514         settings->hdmi_avmute_delay_post_format_change != hdmi->cfg.hdmi_avmute_delay_post_format_change ||
2515         settings->hdmi_color_depth != hdmi->cfg.hdmi_color_depth ||
2516         !BKNI_Memcmp(&settings->hdmi_spdif_channel_status, &hdmi->cfg.hdmi_spdif_channel_status, sizeof(boutput_spdif_channel_status)) )
2517    {
2518        NEXUS_HdmiOutputSettings hdmiSettings;
2519        NEXUS_HdmiOutput_GetSettings(hdmi->handle, &hdmiSettings);
2520        hdmiSettings.preFormatChangeAvMuteDelay = settings->hdmi_avmute_delay_pre_format_change;
2521        hdmiSettings.postFormatChangeAvMuteDelay = settings->hdmi_avmute_delay_post_format_change;
2522        hdmiSettings.preemphasisEnabled = settings->preemphasis_support;
2523        hdmiSettings.colorDepth = settings->hdmi_color_depth;
2524        hdmiSettings.audioChannelStatusInfo.categoryCode = settings->hdmi_spdif_channel_status.category_code;
2525        hdmiSettings.audioChannelStatusInfo.clockAccuracy = settings->hdmi_spdif_channel_status.clock_accuracy;
2526        hdmiSettings.audioChannelStatusInfo.professionalMode = settings->hdmi_spdif_channel_status.professional_mode;
2527        hdmiSettings.audioChannelStatusInfo.swCopyRight = settings->hdmi_spdif_channel_status.copyright;
2528        errCode = NEXUS_HdmiOutput_SetSettings(hdmi->handle, &hdmiSettings);
2529        if ( errCode )
2530        {
2531            return BSETTOP_ERROR(berr_external_error);
2532        }
2533    }
2534
2535#else
2536    BSTD_UNUSED(hdmi);
2537    BSTD_UNUSED(settings);
2538#endif
2539
2540    return b_ok;
2541}
2542
2543void boutput_hdmi_get(boutput_hdmi_t hdmi, boutput_hdmi_settings *settings)
2544{
2545    *settings = hdmi->desired;
2546}
2547
2548bresult boutput_hdmi_get_capabilities(boutput_hdmi_t dvi, boutput_hdmi_capabilities *caps)
2549{
2550#if B_N_DVI_OUTPUTS > 0
2551    NEXUS_HdmiOutputStatus nHdmiStatus;
2552    int i;
2553
2554    BDBG_MSG(("HDMI Get Capabilities"));
2555
2556    NEXUS_HdmiOutput_GetStatus(dvi->handle,&nHdmiStatus);
2557    if(!nHdmiStatus.connected)
2558        return berr_not_available;  /* Soft error -- does not print */
2559
2560    if (bsettop_get_config("hdmi_bypass_edid"))
2561    {
2562        BDBG_MSG(("bypass edid "));
2563        return berr_not_available;
2564    }
2565
2566    caps->hdmi = nHdmiStatus.hdmiDevice;
2567    caps->preferred_video_format = b_nexus2displayformat(nHdmiStatus.preferredVideoFormat, &dvi->desired.vesa_settings);
2568
2569    /* Get all supported video formats */
2570    BKNI_Memset(caps->video_format_is_supported, 0, sizeof(caps->video_format_is_supported));
2571    for(i=0;i<NEXUS_VideoFormat_eMax;i++)
2572    {
2573        if(nHdmiStatus.videoFormatSupported[i])
2574            caps->video_format_is_supported[b_nexus2displayformat(i, NULL)]=true;
2575    }
2576
2577    /* Get all supported audio formats (hdmi only) */
2578    BKNI_Memset(caps->audio_mode_is_supported, 0, sizeof(caps->audio_mode_is_supported));
2579    if(caps->hdmi)
2580    {
2581        caps->audio_mode_is_supported[boutput_hdmi_audio_mode_pcm] = nHdmiStatus.maxAudioPcmChannels?1:0;
2582        if(nHdmiStatus.maxAudioPcmChannels >= 6)
2583            caps->audio_mode_is_supported[boutput_hdmi_audio_mode_pcm_6ch] = true;
2584        /* For compressed, use AC3 to indicate */
2585        if(nHdmiStatus.audioCodecSupported[NEXUS_AudioCodec_eAc3])
2586            caps->audio_mode_is_supported[boutput_hdmi_audio_mode_compressed] = true;
2587
2588        /* HDMI Rx EDID Info */
2589        caps->rx_edid_info.phys_addr_A = nHdmiStatus.physicalAddressA;
2590        caps->rx_edid_info.phys_addr_B = nHdmiStatus.physicalAddressB;
2591        caps->rx_edid_info.phys_addr_C = nHdmiStatus.physicalAddressC;
2592        caps->rx_edid_info.phys_addr_D = nHdmiStatus.physicalAddressD;
2593    }
2594
2595    /* Priority order for preferred audio format */
2596    if ( caps->audio_mode_is_supported[boutput_hdmi_audio_mode_pcm_6ch] )
2597        caps->preferred_audio_mode = boutput_hdmi_audio_mode_pcm_6ch;
2598    else if ( caps->audio_mode_is_supported[boutput_hdmi_audio_mode_compressed] )
2599        caps->preferred_audio_mode = boutput_hdmi_audio_mode_compressed;
2600    else
2601        caps->preferred_audio_mode = boutput_hdmi_audio_mode_pcm;
2602
2603    return b_ok;
2604#else
2605    BSTD_UNUSED(dvi);
2606    BSTD_UNUSED(caps);
2607    return BSETTOP_ERROR(berr_not_supported);
2608#endif
2609
2610}
2611
2612bresult boutput_hdmi_get_status(boutput_hdmi_t dvi, boutput_hdmi_status *status)
2613{
2614    BDBG_ASSERT(NULL != status);
2615
2616    /* Return status as disabled by default */
2617    status->hdcp_state = boutput_hdmi_hdcp_state_disabled;
2618
2619    #if B_N_DVI_OUTPUTS
2620    if ( dvi->desired.hdcp )
2621    {
2622        NEXUS_HdmiOutputHdcpStatus hdcpStatus;
2623
2624        NEXUS_HdmiOutput_GetHdcpStatus(dvi->handle, &hdcpStatus);
2625        switch ( hdcpStatus.hdcpState )
2626        {
2627        case NEXUS_HdmiOutputHdcpState_eUnpowered:
2628            status->hdcp_state = boutput_hdmi_hdcp_state_disabled;
2629            break;
2630        case NEXUS_HdmiOutputHdcpState_eInitializedAuthentication:
2631        case NEXUS_HdmiOutputHdcpState_eWaitForReceiverAuthentication:
2632        case NEXUS_HdmiOutputHdcpState_eReceiverR0Ready:
2633        case NEXUS_HdmiOutputHdcpState_eReceiverAuthenticated:
2634        case NEXUS_HdmiOutputHdcpState_eWaitForRepeaterReady:
2635        case NEXUS_HdmiOutputHdcpState_eCheckForRepeaterReady:
2636        case NEXUS_HdmiOutputHdcpState_eRepeaterReady:
2637        case NEXUS_HdmiOutputHdcpState_eLinkAuthenticated:      /* Includes down stream devices */
2638            status->hdcp_state = boutput_hdmi_hdcp_state_init;
2639            break;
2640        case NEXUS_HdmiOutputHdcpState_eEncryptionEnabled:
2641            status->hdcp_state = boutput_hdmi_hdcp_state_enabled;
2642            break;
2643        case NEXUS_HdmiOutputHdcpState_eUnauthenticated:
2644        case NEXUS_HdmiOutputHdcpState_eR0LinkFailure:
2645            status->hdcp_state = boutput_hdmi_hdcp_state_auth_fail;
2646            break;
2647        case NEXUS_HdmiOutputHdcpState_eRepeaterAuthenticationFailure:
2648            status->hdcp_state = boutput_hdmi_hdcp_state_repeater_fail;
2649            break;
2650        case NEXUS_HdmiOutputHdcpState_eRiLinkIntegrityFailure:
2651            status->hdcp_state = boutput_hdmi_hdcp_state_ri_fail;
2652            break;
2653        case NEXUS_HdmiOutputHdcpState_ePjLinkIntegrityFailure:
2654            status->hdcp_state = boutput_hdmi_hdcp_state_pj_fail;
2655            break;
2656        default:
2657            status->hdcp_state = boutput_hdmi_hdcp_state_internal_err;
2658            break;
2659        }
2660    }
2661    #else
2662    BSTD_UNUSED(dvi);
2663    #endif
2664
2665    return b_ok;
2666}
2667
2668bresult boutput_component_set(boutput_component_t component, const boutput_component_settings *settings)
2669{
2670    component->desired = *settings;
2671    return 0;
2672}
2673
2674void boutput_component_get(boutput_component_t component, boutput_component_settings *settings)
2675{
2676    *settings = component->desired;
2677}
2678
2679bresult boutput_spdif_set(boutput_spdif_t spdif, const boutput_spdif_settings *settings)
2680{
2681    #if B_N_SPDIF_OUTPUTS
2682    NEXUS_SpdifOutputSettings spdifSettings;
2683    BDBG_ASSERT(NULL != spdif);
2684    BDBG_ASSERT(NULL != settings);
2685    NEXUS_SpdifOutput_GetSettings(spdif->handle, &spdifSettings);
2686    spdifSettings.channelStatusInfo.categoryCode = settings->spdif_channel_status.category_code;
2687    spdifSettings.channelStatusInfo.clockAccuracy = settings->spdif_channel_status.clock_accuracy;
2688    spdifSettings.channelStatusInfo.professionalMode = settings->spdif_channel_status.professional_mode;
2689    spdifSettings.channelStatusInfo.swCopyRight = settings->spdif_channel_status.copyright;
2690    if ( NEXUS_SpdifOutput_SetSettings(spdif->handle, &spdifSettings) )
2691    {
2692        return BSETTOP_ERROR(berr_external_error);
2693    }
2694    spdif->desired = *settings;
2695    #else
2696    BSTD_UNUSED(spdif);
2697    BSTD_UNUSED(settings);
2698    #endif
2699    return b_ok;
2700}
2701
2702void boutput_spdif_get(boutput_spdif_t spdif, boutput_spdif_settings *settings)
2703{
2704    BDBG_ASSERT(NULL != spdif);
2705    BDBG_ASSERT(NULL != settings);
2706    *settings = spdif->desired;
2707}
2708
2709boutput_spdif_t
2710boutput_spdif_open(bobject_t id)
2711{
2712#if B_N_SPDIF_OUTPUTS
2713    unsigned index = B_ID_GET_INDEX(id);
2714    if (index >= B_N_SPDIF_OUTPUTS) {
2715        BSETTOP_ERROR(berr_not_available);
2716        return NULL;
2717    }
2718    return &g_spdif[index];
2719#else
2720    BSTD_UNUSED(id);
2721    return NULL;
2722#endif
2723}
2724
2725boutput_rf_t
2726boutput_rf_open(bobject_t id)
2727{
2728#if B_N_RF_OUTPUTS
2729    unsigned index = B_ID_GET_INDEX(id);
2730    if (index >= B_N_RF_OUTPUTS) {
2731        BSETTOP_ERROR(berr_not_available);
2732        return NULL;
2733    }
2734    return &g_rf[index];
2735#else
2736    BSTD_UNUSED(id);
2737    return NULL;
2738#endif
2739}
2740
2741boutput_composite_t
2742boutput_composite_open(bobject_t id)
2743{
2744#if B_N_COMPOSITE_OUTPUTS
2745#if BCHP_CHIP==7420 && id==1 && B_N_COMPOSITE_OUTPUTS == 1
2746    BSTD_UNUSED(id);
2747    return NULL;
2748#endif
2749    unsigned index = B_ID_GET_INDEX(id);
2750    if (index >= B_N_COMPOSITE_OUTPUTS) {
2751        BSETTOP_ERROR(berr_not_available);
2752        return NULL;
2753    }
2754    return &g_composite[index];
2755#else
2756    BSTD_UNUSED(id);
2757    return NULL;
2758#endif
2759}
2760
2761boutput_svideo_t
2762boutput_svideo_open(bobject_t id)
2763{
2764#if B_N_SVIDEO_OUTPUTS
2765    unsigned index = B_ID_GET_INDEX(id);
2766    if (index >= B_N_SVIDEO_OUTPUTS) {
2767        BSETTOP_ERROR(berr_not_available);
2768        return NULL;
2769    }
2770    return &g_svideo[index];
2771#else
2772    BSTD_UNUSED(id);
2773    return NULL;
2774#endif
2775}
2776
2777boutput_hdmi_t
2778boutput_hdmi_open(bobject_t id)
2779{
2780#if B_N_DVI_OUTPUTS
2781    unsigned index = B_ID_GET_INDEX(id);
2782    if (index >= B_N_DVI_OUTPUTS) {
2783        BSETTOP_ERROR(berr_not_available);
2784        return NULL;
2785    }
2786    return &g_hdmi[index];
2787#else
2788    BSTD_UNUSED(id);
2789    return NULL;
2790#endif
2791}
2792
2793boutput_component_t
2794boutput_component_open(bobject_t id)
2795{
2796#if B_N_COMPONENT_OUTPUTS
2797    unsigned index = B_ID_GET_INDEX(id);
2798    if (index >= B_N_COMPONENT_OUTPUTS) {
2799        BSETTOP_ERROR(berr_not_available);
2800        return NULL;
2801    }
2802    return &g_component[index];
2803#else
2804    BSTD_UNUSED(id);
2805    return NULL;
2806#endif
2807}
2808
2809void bdisplay_get_video_format_settings(const bdisplay_settings *settings, bvideo_format_settings *format_settings)
2810{
2811    if (is_panel_output()) {
2812        NEXUS_VideoFormatInfo formatInfo;
2813        NEXUS_VideoFormat_GetInfo(NEXUS_VideoFormat_eCustom0, &formatInfo );
2814        format_settings->width = (unsigned) formatInfo.digitalWidth;
2815        format_settings->height = (unsigned) formatInfo.digitalHeight;
2816        format_settings->interlaced = formatInfo.interlaced;
2817        format_settings->refresh_rate = formatInfo.verticalFreq == 5000 ? 50 : 60;
2818        format_settings->frame_rate = formatInfo.verticalFreq;
2819    }
2820    else {
2821        /* get format settings from enum or vesa_settings */
2822        if (settings->format == bvideo_format_vesa) {
2823            *format_settings = settings->vesa_settings;
2824        }
2825        else {
2826            bvideo_get_format_settings(settings->format, format_settings);
2827        }
2828    }
2829}
2830
2831void bvideo_get_format_settings(bvideo_format format, bvideo_format_settings *settings)
2832{
2833    NEXUS_VideoFormatInfo formatInfo;
2834
2835    BKNI_Memset(settings, 0, sizeof(*settings));
2836
2837    if (format == bvideo_format_vesa) {
2838        BDBG_ERR(("There are multiple options for vesa settings, so you shold use bdisplay_get. "
2839            "See bdisplay_settings.vesa_settings."));
2840        /* TODO: This is a bit ugly. Just pick one vesa mode instead of sending 0's.
2841        The caller should be used bdisplay_get for vesa. */
2842        settings->width = 640;
2843        settings->height = 480;
2844        settings->refresh_rate = 60;
2845        /* 20061213 bandrews - added to record drop_frame status */
2846        settings->frame_rate = bvideo_frame_rate_60; /* TODO: correct??? */
2847        return;
2848    }
2849
2850    NEXUS_VideoFormat_GetInfo(b_displayformat2nexus(format, NULL), &formatInfo );
2851    settings->width = (unsigned) formatInfo.digitalWidth;
2852    settings->height = (unsigned) formatInfo.digitalHeight;
2853    settings->interlaced = formatInfo.interlaced;
2854    settings->refresh_rate = formatInfo.verticalFreq == 5000 ? 50 : 60;
2855    settings->frame_rate = formatInfo.verticalFreq;
2856}
2857
2858/* For settop api defaults which don't match nexus defaults, force them here. */
2859bresult bdecode_window_p_set_initial_settings(bdecode_window_t window)
2860{
2861    NEXUS_VideoWindowSettings nWindowSettings;
2862    NEXUS_Error rc;
2863
2864    NEXUS_VideoWindow_GetSettings(window->nWindow, &nWindowSettings);
2865    if (b_window_is_full_screen(&window->display->settings,
2866                                &window->settings.position)) {
2867        nWindowSettings.contentMode = window->display->settings.content_mode; /* CASSERT for this mapping is elsewhere */
2868    }
2869    else {
2870        /* PIP is always full */
2871        nWindowSettings.contentMode = NEXUS_VideoWindowContentMode_eFull;
2872    }
2873    rc = NEXUS_VideoWindow_SetSettings(window->nWindow, &nWindowSettings);
2874    if (rc) return BSETTOP_ERROR(rc);
2875
2876    return 0;
2877}
2878
2879bdecode_window_t bdecode_window_open(bobject_t window_id, bdisplay_t display)
2880{
2881    unsigned index = B_ID_GET_INDEX(window_id);
2882    bdecode_window_t window;
2883
2884    if (index >= display->numWindowsSupported) {
2885        BSETTOP_ERROR(berr_not_available);
2886        return NULL;
2887    }
2888    window = &display->window[index];
2889    if (window->nWindow) {
2890        BSETTOP_ERROR(berr_not_available);
2891        return NULL;
2892    }
2893
2894    window->nWindow = NEXUS_VideoWindow_Open(display->nDisplay, index);
2895    if (!window->nWindow) {
2896        BSETTOP_ERROR(berr_not_available);
2897        return NULL;
2898    }
2899
2900#if BCHP_CHIP == 7420
2901    /* Set Mad Owner to be the main window on main display */
2902    if (index == 0)
2903    {
2904        gWindowMadOwner = window;
2905    }
2906#endif
2907
2908    /* do not apply setting as we are not ready */
2909    NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eManual);
2910    bsettop_p_display_zorder_add(display,window,window->settings.zorder);
2911    NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eAuto);
2912
2913    bdecode_window_p_set_initial_settings(window);
2914
2915    return window;
2916}
2917
2918bdecode_window_t bdecode_window_open_mosaic(bdecode_window_t parent_window, bobject_t mosaic_id)
2919{
2920    /* TODO */
2921    BSTD_UNUSED(parent_window);
2922    BSTD_UNUSED(mosaic_id);
2923    BSETTOP_ERROR(berr_not_supported);
2924    return NULL;
2925}
2926
2927void
2928bdecode_window_close(bdecode_window_t window)
2929{
2930    bsettop_p_display_zorder_remove( window->display,window);
2931
2932    if ( window->nWindow ) {
2933        NEXUS_VideoWindow_Close(window->nWindow);
2934        window->nWindow = NULL;
2935    }
2936    if (window->clone) {
2937        BDBG_ERR(("must close the clone before closing the parent"));
2938        /* make the best of it. */
2939        window->clone->parent = NULL;
2940        window->clone = NULL;
2941    }
2942    if (window->parent) {
2943        window->parent->clone = NULL;
2944        window->parent = NULL;
2945#if B_N_RF_OUTPUTS
2946        if ( window->display->settings.rf )
2947        {
2948            int i;
2949
2950            for ( i = 0; i < B_N_WINDOWS; i++ )
2951            {
2952                if ( window->display->window[i].parent )
2953                {
2954                    return;
2955                }
2956            }
2957
2958            /* Move RFM back to main window */
2959            b_set_rfm_audio_source(window->display->settings.rf, window->display);
2960        }
2961#endif
2962    }
2963}
2964
2965bdecode_window_t bdecode_window_clone(bdecode_window_t parent_window, bobject_t clone_window_id, bdisplay_t display)
2966{
2967    unsigned index = B_ID_GET_INDEX(clone_window_id);
2968    bdecode_window_t window;
2969
2970    if (index >= display->numWindowsSupported * g_numDisplays) {
2971        BSETTOP_ERROR(berr_not_available);
2972        return NULL;
2973    }
2974    index -= display->index * display->numWindowsSupported;
2975    window = &display->window[index];
2976    if (window->nWindow) {
2977        BSETTOP_ERROR(berr_not_available);
2978        return NULL;
2979    }
2980
2981    window->nWindow = NEXUS_VideoWindow_Open(display->nDisplay, index);
2982    if (!window->nWindow) {
2983        BSETTOP_ERROR(berr_not_available);
2984        return NULL;
2985    }
2986    window->parent = parent_window;
2987    parent_window->clone = window;
2988
2989    /* do not apply setting at this time */
2990    NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eManual);
2991    bsettop_p_display_zorder_add(display,window,window->settings.zorder);
2992    NEXUS_DisplayModule_SetUpdateMode(NEXUS_DisplayUpdateMode_eAuto);
2993
2994    window->settings.cloned = true;
2995
2996    bdecode_window_p_set_initial_settings(window);
2997
2998#if B_N_RF_OUTPUTS
2999    /* If we're cloning, we need to make sure audio for the RFM comes from the primary display's mixer */
3000    if ( display->settings.rf )
3001    {
3002        b_set_rfm_audio_source(display->settings.rf, parent_window->display);
3003    }
3004#endif
3005
3006    return window;
3007}
3008
3009bresult bdisplay_set_dac_audio_volume(bdisplay_t display, const baudio_volume *volume)
3010{
3011    bresult rc;
3012    if (display->audioDac.handle) {
3013        BDBG_MSG(("Setting DAC volume"));
3014        rc = bdisplay_p_set_output_volume(NEXUS_AudioDac_GetConnector(display->audioDac.handle), volume, &display->volume, false);
3015        if ( rc ) { return BSETTOP_ERROR(rc); }
3016    }
3017    else
3018    {
3019        BDBG_MSG(("Not Setting DAC volume -- No DAC on this display"));
3020    }
3021
3022    return b_ok;
3023}
3024
3025bresult boutput_rf_set_audio_volume(boutput_rf_t rf, const baudio_volume *volume)
3026{
3027#if B_N_RF_OUTPUTS
3028    NEXUS_RfmSettings rfmSettings;
3029    NEXUS_Error rc;
3030
3031    NEXUS_Rfm_GetSettings(rf->handle, &rfmSettings);
3032    rfmSettings.muted = volume->muted;
3033    /* volume level is ignored. it is set with the dac. */
3034    rc = NEXUS_Rfm_SetSettings(rf->handle, &rfmSettings);
3035    if (rc) return BSETTOP_ERROR(berr_external_error);
3036    return 0;
3037#else
3038    BSTD_UNUSED(rf);
3039    BSTD_UNUSED(volume);
3040    return BSETTOP_ERROR(berr_not_supported);
3041#endif
3042}
3043
3044bresult boutput_rf_get_audio_volume(boutput_rf_t rf, baudio_volume *volume)
3045{
3046#if B_N_RF_OUTPUTS
3047    NEXUS_RfmSettings rfmSettings;
3048    NEXUS_Rfm_GetSettings(rf->handle, &rfmSettings);
3049    volume->muted = rfmSettings.muted;
3050    volume->left = volume->right = 0; /* unused */
3051    return 0;
3052#else
3053    BSTD_UNUSED(rf);
3054    BSTD_UNUSED(volume);
3055    return BSETTOP_ERROR(berr_not_supported);
3056#endif
3057}
3058
3059bresult boutput_spdif_set_audio_volume(boutput_spdif_t spdif, const baudio_volume *volume)
3060{
3061    #if B_N_SPDIF_OUTPUTS || B_N_DVI_OUTPUTS
3062    bresult rc;
3063    bool force_mute;
3064    #endif
3065    #if B_N_SPDIF_OUTPUTS
3066    force_mute = (false == spdif->cfg.pcm && spdif->compressed_mute)?true:false;    /* If in compressed mode and decoder wants a mute, mute. */
3067    rc = bdisplay_p_set_output_volume(NEXUS_SpdifOutput_GetConnector(spdif->handle), volume, &spdif->volume, force_mute);
3068    if ( rc ) return BSETTOP_ERROR(rc);
3069    #endif
3070    #if B_N_DVI_OUTPUTS
3071    BDBG_MSG(("Checking HDMI display %p dvi %p", spdif->display, (spdif->display)?spdif->display->settings.dvi:NULL));
3072    if ( spdif->display && spdif->display->settings.dvi )
3073    {
3074        boutput_hdmi_t hdmi = spdif->display->settings.dvi;
3075        NEXUS_HdmiOutputHdcpStatus hdcpStatus;
3076
3077        if ( hdmi->desired.hdcp && !hdmi->desired.hdcp_disable_blue_screen)
3078        {
3079            NEXUS_HdmiOutput_GetHdcpStatus(hdmi->handle, &hdcpStatus);
3080            BDBG_MSG(("hdcpStatus=%d (left=%d right=%d mute=%d)", hdcpStatus.hdcpState, volume->left, volume->right, volume->muted));
3081
3082            switch ( hdcpStatus.hdcpState )
3083            {
3084            case NEXUS_HdmiOutputHdcpState_eLinkAuthenticated:
3085            case NEXUS_HdmiOutputHdcpState_eEncryptionEnabled:
3086                BDBG_MSG(("HDCP Succeeded. Setting HDMI volume "));
3087                                rc = bdisplay_p_set_output_volume(NEXUS_HdmiOutput_GetAudioConnector(spdif->display->settings.dvi->handle), volume, &spdif->volume, force_mute);
3088                if ( rc ) return BSETTOP_ERROR(rc);
3089                break;
3090
3091            default:
3092                /* leave audio intact - muted */
3093                break;
3094            }
3095        }
3096        else
3097        {
3098            BDBG_MSG(("Setting HDMI volume"));
3099                        rc = bdisplay_p_set_output_volume(NEXUS_HdmiOutput_GetAudioConnector(spdif->display->settings.dvi->handle), volume, &spdif->volume, force_mute);
3100            if ( rc ) return BSETTOP_ERROR(rc);
3101        }
3102    }
3103    #endif
3104    return b_ok;
3105}
3106
3107bresult bdisplay_get_dac_audio_volume(bdisplay_t display, baudio_volume *volume)
3108{
3109    *volume = display->volume;
3110    return b_ok;
3111}
3112
3113bresult boutput_spdif_get_audio_volume(boutput_spdif_t spdif, baudio_volume *volume)
3114{
3115    *volume = spdif->volume;
3116    return b_ok;
3117}
3118
3119void bdisplay_p_enable_audio(bdisplay_t display, bool enabled)
3120{
3121    unsigned i;
3122
3123    B_LOCK_ASSERT();
3124
3125    /* Handle recursion. */
3126    if ( enabled )
3127    {
3128        BDBG_ASSERT(display->audioDisableCount > 0);
3129        display->audioDisableCount--;
3130        if ( display->audioDisableCount > 0 )
3131        {
3132            return;
3133        }
3134    }
3135    else
3136    {
3137        display->audioDisableCount++;
3138        if ( display->audioDisableCount > 1 )
3139        {
3140            return;
3141        }
3142    }
3143
3144    /* Disable any pcm playback operations -- must do this before decode. */
3145    bpcm_play_p_enable(display, enabled);
3146
3147    /* Loop through windows with decode active and enable/disable audio decoder */
3148    for (i = 0; i < display->numWindowsSupported; i++)
3149    {
3150        bdecode_window_t window = &display->window[i];
3151        if ( window && window->decode )
3152        {
3153            /* Found window with active audio decode */
3154            BDBG_MSG(("setting audio decode %p enable state to %d", window->decode, enabled));
3155            bdecode_p_enable_audio(window->decode, enabled);
3156        }
3157    }
3158}
3159
3160int b_volume2nexus(int settop_vol, bool decibel, int *out_volume)
3161{
3162    BDBG_ASSERT(NULL != out_volume);
3163    if (settop_vol > BAUDIO_LEVEL_MAX) settop_vol = BAUDIO_LEVEL_MAX;
3164    if (settop_vol < BAUDIO_LEVEL_MIN) settop_vol = BAUDIO_LEVEL_MIN;
3165    *out_volume = settop_vol;
3166    if (decibel) {
3167        /* TODO: when AudioMixer supports linear, get rid of the decibel option in this function */
3168        /* Volume = bvol * nmax / bmin */
3169        settop_vol = BAUDIO_LEVEL_MAX-settop_vol;   /* DB is an inverted scale - higher numbers = smaller volume */
3170        return settop_vol * NEXUS_AUDIO_VOLUME_DB_MIN / BAUDIO_LEVEL_MAX;
3171    }
3172    else {
3173        return ((settop_vol + NEXUS_AUDIO_VOLUME_LINEAR_MIN - BAUDIO_LEVEL_MIN) * (NEXUS_AUDIO_VOLUME_LINEAR_NORMAL - NEXUS_AUDIO_VOLUME_LINEAR_MIN)) / (BAUDIO_LEVEL_MAX - BAUDIO_LEVEL_MIN);
3174    }
3175}
3176
3177/* This is identical for all outputs except RFM */
3178static bresult bdisplay_p_set_output_volume(NEXUS_AudioOutput output, const baudio_volume *volume, baudio_volume *out_volume, bool force_mute)
3179{
3180    NEXUS_Error rc;
3181    NEXUS_AudioOutputSettings nSettings;
3182
3183    BDBG_ASSERT(NULL != output);
3184    BDBG_ASSERT(NULL != volume);
3185    BDBG_ASSERT(NULL != out_volume);
3186
3187    *out_volume = *volume;
3188
3189    NEXUS_AudioOutput_GetSettings(output, &nSettings);
3190    nSettings.volumeType = NEXUS_AudioVolumeType_eLinear;
3191    nSettings.leftVolume = b_volume2nexus(volume->left, false, &out_volume->left);
3192    nSettings.rightVolume = b_volume2nexus(volume->right, false, &out_volume->right);
3193    BDBG_MSG(("set volume %d -> %d", volume->left, nSettings.leftVolume));
3194    nSettings.muted = volume->muted || force_mute;
3195    rc = NEXUS_AudioOutput_SetSettings(output, &nSettings);
3196    if (rc) return BSETTOP_ERROR(berr_external_error);
3197
3198    return b_ok;
3199}
3200
3201
3202bresult boutput_hdmi_cec_get_message(boutput_hdmi_t dvi, boutput_hdmi_cec_message_data *cec_message_data )
3203{
3204    bresult src = b_ok;
3205
3206#if B_N_DVI_OUTPUTS > 0
3207    NEXUS_Error rc = NEXUS_SUCCESS;
3208    NEXUS_HdmiOutputCecMessageData stRecvCecMsg;
3209    NEXUS_HdmiOutputCecMessageStatus stCecMessageStatus;
3210
3211    /* zero out the cec message data structure before proceeding */
3212    BKNI_Memset(cec_message_data, 0, sizeof(boutput_hdmi_cec_message_data));
3213
3214    /* Check if Rx or Tx Event */
3215    NEXUS_HdmiOutput_GetCecMessageInfo(dvi->handle, &stCecMessageStatus);
3216
3217    /* RECEIVED Messages/Status */
3218    if (stCecMessageStatus.eCecMessageType == NEXUS_HdmiOutputCecIntMessageType_eReceive)
3219    {
3220        if ((rc = NEXUS_HdmiOutput_ReceiveCecMessage(dvi->handle, &stRecvCecMsg))
3221            != NEXUS_SUCCESS)
3222        {
3223            src = berr_external_error;
3224            goto done;
3225        }
3226
3227        /* parse CEC message data */
3228        cec_message_data->message_type = boutput_hdmi_cec_message_type_receive;
3229        cec_message_data->initiator_addr = stRecvCecMsg.initiatorAddr;
3230        cec_message_data->destination_addr = stRecvCecMsg.destinationAddr;
3231        cec_message_data->opcode = stRecvCecMsg.messageBuffer[0];
3232        cec_message_data->message_length = stRecvCecMsg.messageLength;
3233        BKNI_Memcpy(&cec_message_data->message_buffer, &stRecvCecMsg.messageBuffer,
3234            (sizeof(uint8_t) * stRecvCecMsg.messageLength));
3235
3236
3237        /* always enable receive after CEC message is processed */
3238        NEXUS_HdmiOutput_EnableCecReceive(dvi->handle);
3239    }
3240
3241    /* TRANSMITTED Message Status */
3242    else if (stCecMessageStatus.eCecMessageType == NEXUS_HdmiOutputCecIntMessageType_eTransmit)
3243    {
3244        cec_message_data->message_type = boutput_hdmi_cec_message_type_transmit;
3245
3246        BDBG_MSG(("HDMI CEC Xmit Msg done")) ;
3247        /* process accordingly */
3248    }
3249    else
3250    {
3251        BDBG_ERR(("Unknown HDMI CEC Message Type %d", stCecMessageStatus.eCecMessageType)) ;
3252        src = berr_invalid_parameter;
3253        goto done;
3254    }
3255
3256done:
3257#else
3258    BSTD_UNUSED(dvi);
3259    BSTD_UNUSED(cec_message_data);
3260#endif
3261
3262    return src;
3263}
3264
3265
3266bresult boutput_hdmi_cec_send_message(boutput_hdmi_t dvi, const boutput_hdmi_cec_message_data *cec_message_data )
3267{
3268    bresult src = b_ok;
3269
3270#if B_N_DVI_OUTPUTS > 0
3271    NEXUS_Error rc = NEXUS_SUCCESS;
3272    NEXUS_HdmiOutputCecMessageData stXmitCecMsg;
3273
3274    if (!dvi)
3275        return(b_ok);       /* no DVI/HDMI device connected */
3276
3277    /* Copy CEC transmit message data */
3278    stXmitCecMsg.destinationAddr = cec_message_data->destination_addr;
3279    stXmitCecMsg.messageLength = cec_message_data->message_length;
3280    BKNI_Memcpy(&stXmitCecMsg.messageBuffer, &cec_message_data->message_buffer,
3281        (sizeof(uint8_t) * cec_message_data->message_length));
3282
3283    rc = NEXUS_HdmiOutput_SendCecMessage(dvi->handle, &stXmitCecMsg);
3284    if (rc != NEXUS_SUCCESS)
3285    {
3286        BDBG_WRN(("Error sending CEC message"));
3287        src = BSETTOP_ERROR(rc);
3288    }
3289
3290#else
3291    BSTD_UNUSED(dvi);
3292    BSTD_UNUSED(cec_message_data);
3293#endif
3294
3295    return src;
3296}
3297
3298
3299bresult boutput_hdmi_cec_get_configuration(boutput_hdmi_t dvi, boutput_hdmi_cec_configuration *cec_configuration )
3300{
3301    bresult src = b_ok;
3302
3303#if B_N_DVI_OUTPUTS > 0
3304    NEXUS_Error rc = NEXUS_SUCCESS;
3305    NEXUS_HdmiOutputCecConfiguration stConfiguration;
3306
3307    /* zero out the cec data structure before proceeding */
3308    BKNI_Memset(cec_configuration, 0, sizeof(boutput_hdmi_cec_configuration));
3309
3310    /* get cec configuration */
3311    rc = NEXUS_HdmiOutput_GetCecConfiguration(dvi->handle, &stConfiguration);
3312    if (rc != NEXUS_SUCCESS)
3313    {
3314        goto done;
3315    }
3316
3317    cec_configuration->logical_address = stConfiguration.logicalAddress;
3318    BKNI_Memcpy(&cec_configuration->physical_address, &stConfiguration.physicalAddress,
3319        sizeof(stConfiguration.physicalAddress));
3320    cec_configuration->device_type = stConfiguration.deviceType;
3321
3322done:
3323#else
3324    BSTD_UNUSED(dvi);
3325    BSTD_UNUSED(cec_configuration);
3326#endif
3327
3328    return src;
3329}
3330
3331
3332bool boutput_hdmi_cec_is_device_ready(boutput_hdmi_t dvi)
3333{
3334
3335#if B_N_DVI_OUTPUTS > 0
3336    return NEXUS_HdmiOutput_IsCecDeviceReady(dvi->handle);
3337#else
3338    BSTD_UNUSED(dvi);
3339    return false;
3340#endif
3341
3342}
3343
3344
3345bresult boutput_hdmi_cec_enable_receive(boutput_hdmi_t dvi)
3346{
3347    bresult src = b_ok;
3348
3349#if B_N_DVI_OUTPUTS > 0
3350    NEXUS_Error rc = NEXUS_SUCCESS;
3351
3352    rc = NEXUS_HdmiOutput_EnableCecReceive(dvi->handle);
3353    if (rc != NEXUS_SUCCESS)
3354        src = berr_external_error;
3355#else
3356    BSTD_UNUSED(dvi);
3357#endif
3358
3359    return src;
3360}
3361
3362/* must be in manual update mode before calling this */
3363static void
3364bsettop_p_display_apply_zorder(bdisplay_t display)
3365{
3366    int i;
3367    BERR_Code rc;
3368    NEXUS_VideoWindowSettings nSettings;
3369    int numZorder = sizeof(display->zorderList)/sizeof(*display->zorderList);
3370
3371    for(i=0; i<numZorder; i++) {
3372        if (display->zorderList[i].window==NULL) {
3373            break;
3374        }
3375        BDBG_MSG(("display %p window %#x zorder %u(%u)", display,display->zorderList[i].window, display->zorderList[i].zorder, i));
3376        NEXUS_VideoWindow_GetSettings(display->zorderList[i].window->nWindow, &nSettings);
3377        nSettings.zorder = i;
3378        rc =NEXUS_VideoWindow_SetSettings(display->zorderList[i].window->nWindow, &nSettings);
3379        if (rc!=BERR_SUCCESS) { BSETTOP_ERROR(berr_external_error);break;}
3380    }
3381    return;
3382}
3383
3384
3385static void
3386bsettop_p_display_zorder_add(bdisplay_t display, bdecode_window_t window, unsigned zorder)
3387{
3388    int i;
3389    int index;
3390    int numZorder = sizeof(display->zorderList)/sizeof(*display->zorderList);
3391
3392    BDBG_MSG(("zorder_add display %p window %p zorder %d",display,window,zorder));
3393
3394    for(i=0; i<numZorder; i++) {
3395        if (display->zorderList[i].window == window) {
3396            BDBG_MSG(("zorder: display %#x duplicate window %#x", (unsigned)display, (unsigned)window));
3397            return;
3398        }
3399    }
3400
3401    for(index=-1,i=0; i<numZorder; i++) {
3402        if (display->zorderList[i].window == NULL || display->zorderList[i].zorder > zorder) {
3403            index = i;
3404            break;
3405        }
3406    }
3407    if (index==-1) {
3408        BDBG_ERR(("zorder: display %#x overflow", (unsigned)display));
3409        return;
3410    }
3411    /* shift windows up */
3412    for(i=numZorder-1; i>index;i--) {
3413        if (display->zorderList[i-1].window == NULL) {
3414            continue;
3415        }
3416        display->zorderList[i] = display->zorderList[i-1];
3417    }
3418    display->zorderList[index].window = window;
3419    display->zorderList[index].zorder = zorder;
3420    bsettop_p_display_apply_zorder(display);
3421    return;
3422}
3423
3424static void
3425bsettop_p_display_zorder_remove(bdisplay_t display , bdecode_window_t window)
3426{
3427    int i;
3428    int index;
3429    int numZorder = sizeof(display->zorderList)/sizeof(*display->zorderList);
3430
3431    BDBG_MSG(("zorder_remove display %p window %p",display,window));
3432
3433    for(index=-1,i=0; i<numZorder; i++) {
3434        if (display->zorderList[i].window == window) {
3435            index = i;
3436            break;
3437        }
3438    }
3439    if (index == -1 ) {
3440        BDBG_ERR(("zorder: display %#x invalid window %#x", (unsigned)display, (unsigned)window));
3441        return;
3442    }
3443    /* shift windows down */
3444    display->zorderList[index].window = NULL;
3445    for(i=index;i<numZorder-1; i++) {
3446        if (display->zorderList[i+1].window == NULL) {
3447            break;
3448        }
3449        display->zorderList[i] = display->zorderList[i+1];
3450    }
3451    /* don't reapply zorder on remove */
3452    return;
3453}
3454
3455static void
3456bsettop_p_display_zorder_set(bdisplay_t display , bdecode_window_t window , unsigned zorder)
3457{
3458    int i;
3459    int index;
3460    struct zorder_item temp;
3461    int numZorder = sizeof(display->zorderList)/sizeof(*display->zorderList);
3462
3463    BDBG_MSG(("zorder_set display %p window %p zorder %d",display,window,zorder));
3464
3465    for(index=-1,i=0; i<numZorder; i++) {
3466        if (display->zorderList[i].window == window) {
3467            index = i;
3468            break;
3469        }
3470    }
3471    if (index==-1) {
3472        BDBG_ERR(("zorder: display %#x unknown window %#x", (unsigned)display, (unsigned)window));
3473        return;
3474    }
3475    if (zorder > display->zorderList[i].zorder) { /* we should move window up */
3476        display->zorderList[i].zorder = zorder;
3477        for(i=index+1; i<numZorder;  i++) {
3478            if (display->zorderList[i].window==NULL) {
3479                /* reached last entry */
3480                break;
3481            }
3482            if (display->zorderList[i].zorder<zorder) {
3483                /* swap two entries */
3484                temp = display->zorderList[index];
3485                display->zorderList[index] = display->zorderList[i];
3486                display->zorderList[i] = temp;
3487                index = i;
3488            } else {
3489                break;
3490            }
3491        }
3492    } else if (zorder < display->zorderList[i].zorder) { /* we should move window down */
3493        display->zorderList[i].zorder = zorder;
3494        for(i=index-1; i>=0; i--) {
3495            BDBG_ASSERT(display->zorderList[i].window); /* this shall never happen */
3496            if (display->zorderList[i].zorder>zorder) {
3497                /* swap two entries */
3498                temp = display->zorderList[index];
3499                display->zorderList[index] = display->zorderList[i];
3500                display->zorderList[i] = temp;
3501                index = i;
3502            } else {
3503                break;
3504            }
3505        }
3506    }
3507    bsettop_p_display_apply_zorder(display);
3508    return;
3509}
3510
3511bool
3512b_window_is_full_screen(const bdisplay_settings *display_settings, const bsettop_rect *position)
3513{
3514    bvideo_format_settings format_settings;
3515
3516    bdisplay_get_video_format_settings(display_settings, &format_settings);
3517
3518    /* NTSC height is now 482, but we need to treat 480 as full-screen,
3519    therefore just mask off the low order bits on height comparison. */
3520    if (position->x == 0 &&
3521        position->y == 0 &&
3522        position->width == format_settings.width &&
3523        (position->height&0xFFFD) == (format_settings.height&0xFFFD)) {
3524        return true;
3525    }
3526    return false;
3527}
3528
3529void bdisplay_p_set_compressed_mute(bdisplay_t display, bool compressed_mute)
3530{
3531    if ( display->settings.dvi )
3532    {
3533        display->settings.dvi->compressed_mute = compressed_mute;
3534    }
3535    if ( display->settings.spdif )
3536    {
3537        display->settings.spdif->compressed_mute = compressed_mute;
3538        /* This sets both SPDIF and HDMI volumes */
3539        boutput_spdif_set_audio_volume(display->settings.spdif, &display->settings.spdif->volume);
3540    }
3541}
3542
3543#if B_N_RF_OUTPUTS
3544static bresult b_set_rfm_audio_source(boutput_rf_t rf, bdisplay_t display)
3545{
3546    NEXUS_Error rc;
3547
3548    if ( display != rf->master_display )
3549    {
3550        if ( rf->master_display )
3551        {
3552            bdisplay_p_enable_audio(rf->master_display, false);
3553            rc = NEXUS_AudioOutput_RemoveAllInputs(NEXUS_Rfm_GetAudioConnector(rf->handle));
3554            bdisplay_p_enable_audio(rf->master_display, true);
3555            if (rc) return BSETTOP_ERROR(berr_external_error);
3556            rf->master_display = NULL;
3557        }
3558        if ( display )
3559        {
3560            bdisplay_p_enable_audio(display, false);
3561            rc = NEXUS_AudioOutput_AddInput(NEXUS_Rfm_GetAudioConnector(rf->handle),
3562                                            NEXUS_AudioMixer_GetConnector(display->nAudioMixer));
3563            bdisplay_p_enable_audio(display, true);
3564            if (rc) return BSETTOP_ERROR(berr_external_error);
3565            rf->master_display = display;
3566        }
3567    }
3568    return 0;
3569}
3570#endif
3571
3572void bdisplay_p_decode_starting(bdisplay_t display, bdecode_window_t window, bdecode_t decode)
3573{
3574    unsigned outputTimebase = display->outputTimebase;
3575    bdecode_t master = NULL;
3576
3577    /* If this is a full-screen window or the primary window, proceed... */
3578    if ( &display->window[0] == window || b_window_is_full_screen(&display->settings, &window->settings.position) )
3579    {
3580        outputTimebase = decode->output_timebase;
3581        master = decode;
3582    }
3583
3584    /* Only update if the timeabase is actually changing */
3585    if ( outputTimebase != display->outputTimebase )
3586    {
3587        bdisplay_p_set_output_timebase(display, outputTimebase);
3588    }
3589
3590    if ( window->clone )
3591    {
3592        /* Clone window.  Check for timebase update. */
3593        bdisplay_p_decode_starting(window->clone->display, window->clone, decode);
3594    }
3595    if ( window->parent )
3596    {
3597        /* This is a cloned window.  No frame rate master */
3598        bdisplay_p_set_framerate_master(display, NULL);
3599    }
3600    else
3601    {
3602        /* Not cloned.  Set master */
3603        bdisplay_p_set_framerate_master(display, master);
3604    }
3605}
3606
3607static void bdisplay_p_set_output_timebase(bdisplay_t display, unsigned timebase)
3608{
3609    NEXUS_DisplaySettings displaySettings;
3610
3611    /* Update display timebase */
3612    NEXUS_Display_GetSettings(display->nDisplay, &displaySettings);
3613    displaySettings.timebase = timebase;
3614    NEXUS_Display_SetSettings(display->nDisplay, &displaySettings);
3615
3616    /* Update audio timebase/pll */
3617    if (display->settings.spdif)
3618    {
3619        BDBG_MSG(("%s: Setting SPDIF Output to timebase %d", __FUNCTION__, timebase));
3620        b_set_audio_output_timebase(NEXUS_SpdifOutput_GetConnector(display->settings.spdif->handle), timebase);
3621    }
3622
3623#if B_N_DVI_OUTPUTS
3624    if (display->settings.dvi)
3625    {
3626        BDBG_MSG(("%s: Setting DVI/HDMI Output to timebase %d", __FUNCTION__, timebase));
3627        b_set_audio_output_timebase(NEXUS_HdmiOutput_GetAudioConnector(display->settings.dvi->handle), timebase);
3628    }
3629#endif
3630
3631    if (display->audioDac.handle)
3632    {
3633        BDBG_MSG(("%s: Setting Audio DACs Output to timebase %d", __FUNCTION__, timebase));
3634        b_set_audio_output_timebase(NEXUS_AudioDac_GetConnector(display->audioDac.handle), timebase);
3635    }
3636
3637    display->outputTimebase = timebase;
3638}
3639
3640static void bdisplay_p_set_framerate_master(bdisplay_t display, bdecode_t master)
3641{
3642    NEXUS_VideoInput masterInput = NULL;
3643    NEXUS_DisplaySettings displaySettings;
3644
3645    if ( master && master->video_decode )
3646    {
3647        masterInput = NEXUS_VideoDecoder_GetConnector(master->video_decode->nVideoDecoder);
3648    }
3649
3650    NEXUS_Display_GetSettings(display->nDisplay, &displaySettings);
3651    if ( displaySettings.frameRateMaster == masterInput )
3652    {
3653        return;
3654    }
3655    displaySettings.frameRateMaster = masterInput;
3656    NEXUS_Display_SetSettings(display->nDisplay, &displaySettings);
3657}
3658
3659static bresult b_set_audio_output_timebase(NEXUS_AudioOutput output, NEXUS_Timebase outputTimebase)
3660{
3661    NEXUS_Error rc;
3662    NEXUS_AudioOutputSettings nSettings;
3663
3664    BDBG_ASSERT(NULL != output);
3665
3666    NEXUS_AudioOutput_GetSettings(output, &nSettings);
3667    nSettings.timebase = outputTimebase;
3668    #if B_MAX_DECODES > 1
3669    nSettings.pll = (outputTimebase & 0x1)?NEXUS_AudioOutputPll_e1:NEXUS_AudioOutputPll_e0;
3670    #endif
3671    rc = NEXUS_AudioOutput_SetSettings(output, &nSettings);
3672    if (rc) return BSETTOP_ERROR(berr_external_error);
3673
3674    return b_ok;
3675}
3676
3677NEXUS_DisplayHandle bdisplay_get_nexus_handle(bdisplay_t display)
3678{
3679        BDBG_ASSERT(NULL != display);
3680        return display->nDisplay;
3681}
3682
3683
Note: See TracBrowser for help on using the repository browser.