source: svn/newcon3bcm2_21bu/magnum/portinginterface/vdc/7552/bvdc_source.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 140.9 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2012, 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: bvdc_source.c $
11 * $brcm_Revision: Hydra_Software_Devel/474 $
12 * $brcm_Date: 3/8/12 11:51a $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/vdc/7038/bvdc_source.c $
19 *
20 * Hydra_Software_Devel/474   3/8/12 11:51a yuxiaz
21 * SW7425-2546: Fixed warning msg.
22 *
23 * Hydra_Software_Devel/473   3/1/12 1:42p yuxiaz
24 * SW7425-2418: Set hHeap for graphics surface.
25 *
26 * Hydra_Software_Devel/472   3/1/12 11:46a yuxiaz
27 * SW7425-2526, SW7425-1182: Added runtime query capabilities for source
28 * in VDC.
29 *
30 * Hydra_Software_Devel/471   2/29/12 2:54p yuxiaz
31 * SW7425-2418: Clean up code for mfd feeds from gfx surface
32 *
33 * Hydra_Software_Devel/470   2/16/12 3:01p vanessah
34 * SW7425-2327: add Bar data handling
35 *
36 * Hydra_Software_Devel/469   2/16/12 1:16p pntruong
37 * SW7231-587: Correctly propagate the original pts value to get buffer.
38 *
39 * Hydra_Software_Devel/468   2/13/12 2:42p yuxiaz
40 * SW7425-2181: Fixed MPEG data validate when
41 * pChrominanceFrameBufferAddress is NULL.
42 *
43 * Hydra_Software_Devel/467   2/8/12 1:40p yuxiaz
44 * SW7405-5577: loss of video on composite on mosaic teardown: remove
45 * unnecessary source slot clean up.
46 *
47 * Hydra_Software_Devel/466   2/7/12 5:14p yuxiaz
48 * SW7425-2181: Add basic VDC support to interface with output from SID
49 * for MJPEG usage mode.
50 *
51 * Hydra_Software_Devel/465   12/8/11 4:41p yuxiaz
52 * SW7425-967: Bring up MRE on 7425 B1.
53 *
54 * Hydra_Software_Devel/464   12/7/11 5:17p pntruong
55 * SW7208-175: Allowed more valid resolution supported by decoder and not
56 * just resticted to 1080p.
57 *
58 * Hydra_Software_Devel/463   12/1/11 4:33p yuxiaz
59 * SW7425-968, SW7344-95: Merged into mainline.: added independent source
60 * clipping of right window in 3D mode.
61 *
62 * Hydra_Software_Devel/SW7425-968/1   11/16/11 3:12p yuxiaz
63 * SW7425-968: Added left_R calculation in VDC rects.
64 *
65 * Hydra_Software_Devel/462   10/27/11 5:31p albertl
66 * SW7405-4434: Fixed to correctly copy content of pCurDirty to pOldDirty
67 * rather than copy pointer values.
68 *
69 * Hydra_Software_Devel/461   10/26/11 2:56p pntruong
70 * SW7400-3008, SW7405-4434: Used correct dirtybit context.
71 *
72 * Hydra_Software_Devel/460   10/7/11 5:49p vanessah
73 * SW7425-1417: add host_arm for STG_1
74 *
75 * Hydra_Software_Devel/459   9/27/11 5:21p yuxiaz
76 * SW7425-967: Bring up MRE on 7425 B0.
77 *
78 * Hydra_Software_Devel/458   9/14/11 5:14p yuxiaz
79 * SW7425-1276: Undo previous change. Move
80 * BVDC_P_Source_UpdateSrcState_isr up.
81 *
82 * Hydra_Software_Devel/457   9/14/11 3:51p yuxiaz
83 * SW7425-1276: Fixed switch between 3DLR and 3DOU.
84 *
85 * Hydra_Software_Devel/456   9/14/11 11:47a yuxiaz
86 * SW7405-5490: Reduce slave slot to 1 for each MFD source in mosaic mode.
87 *
88 * Hydra_Software_Devel/455   9/8/11 10:21a syang
89 * SW7425-1265: honor back to back new setting
90 *
91 * Hydra_Software_Devel/454   9/1/11 9:48p yuxiaz
92 * SW7425-985, SW7425-967: Added MRE support in MFD.
93 *
94 * Hydra_Software_Devel/453   8/27/11 7:23p hongtaoz
95 * SW7425-1132: replaced slip2lock boolean flag with integer counter to
96 * fix a timing sensitive hang conditiion when NRT sync-locked window is
97 * brought up;
98 *
99 * Hydra_Software_Devel/452   8/19/11 1:36p pntruong
100 * SW7425-59: Don't flood the with the repeat message.
101 *
102 * Hydra_Software_Devel/451   7/18/11 11:21a vanessah
103 * SW7425-835: SW7425-923: fix ViCE2 channel id bug + B0 STG
104 *
105 * Hydra_Software_Devel/450   7/8/11 5:22p vanessah
106 * SW7425-832: get rid of the workround and platform dependent limitation
107 *
108 * Hydra_Software_Devel/449   7/1/11 4:06p vanessah
109 * SW7425-832: set monitor refresh rate default value to display refresh
110 * rate when XVD give BFMT_Vert_eInvalid value.
111 *
112 * Hydra_Software_Devel/448   6/28/11 5:24p vanessah
113 * SW7425-788: fix coverity error
114 *
115 * Hydra_Software_Devel/447   6/28/11 4:56p vanessah
116 * SW7425-686: change Srcpolarity when XVD and BVN refreshrate mismatch
117 *
118 * Hydra_Software_Devel/446   6/28/11 9:40a vanessah
119 * SW7425-686: Get rid of black frame
120 *
121 * Hydra_Software_Devel/445   6/27/11 7:58p pntruong
122 * SW7425-772: Fine tuned deinterlacer policy.
123 *
124 * Hydra_Software_Devel/444   6/26/11 5:55p vanessah
125 * SW7425-686: fix XVD and BVN fmt missync by mute MFD
126 *
127 * Hydra_Software_Devel/443   6/10/11 6:27p hongtaoz
128 * SW7425-704: fixed compile error for chips without STG;
129 *
130 * Hydra_Software_Devel/442   6/10/11 5:49p hongtaoz
131 * SW7425-704: add NRT mode support to VDC; moved the STG meta data
132 * passing from window writer isr to reader isr; added bStallStc flag
133 * support;
134 *
135 * Hydra_Software_Devel/441   5/17/11 4:19p yuxiaz
136 * SW7422-446: Added orientation override for graphics source.
137 *
138 * Hydra_Software_Devel/440   5/11/11 3:50p pntruong
139 * SW7231-140: Correctly compute the MFD fieldswap flag.
140 *
141 * Hydra_Software_Devel/439   4/8/11 1:56p yuxiaz
142 * SW7425-236: Fixed flashing when source orientation changes.
143 *
144 * Hydra_Software_Devel/438   3/30/11 4:40p yuxiaz
145 * SW7420-1186: Change BDBG_MSG to BDBG_WRN when VDC gets stream larger
146 * than 720p frame picture.
147 *
148 * Hydra_Software_Devel/437   3/29/11 1:42p yuxiaz
149 * SW7422-143, SW7425-236: Added new source dirty bit for orientation
150 * change. Fixed flashing when source orientation changes.
151 *
152 * Hydra_Software_Devel/436   2/24/11 4:51p albertl
153 * SW7425-59: Changed debug message from BDBG_WRN.
154 *
155 * Hydra_Software_Devel/435   2/24/11 4:33p albertl
156 * SW7405-4434: Fixed ApplyChanges taking more than one vsync on sync
157 * locked windows.
158 *
159 * Hydra_Software_Devel/434   2/10/11 1:17p hongtaoz
160 * SW7425-59: updated buffer repeat debug message;
161 *
162 * Hydra_Software_Devel/433   2/4/11 4:21p yuxiaz
163 * SW7550-661: About shake of screen when NEXUS_VideoWindow_AddInput call.
164 *
165 * Hydra_Software_Devel/432   12/29/10 6:12p pntruong
166 * SW7422-175: Scan out SVC 1080p@60 content as 1080p and not 1080i.
167 *
168 * Hydra_Software_Devel/431   12/20/10 5:46p yuxiaz
169 * SW7422-34: Added BVDC_Source_SetOrientation and
170 * BVDC_Source_GetOrientation.
171 *
172 * Hydra_Software_Devel/430   12/9/10 9:51a yuxiaz
173 * SW7422-39: Added more debug message for 3d.
174 *
175 * Hydra_Software_Devel/429   12/8/10 5:44p tdo
176 * SW7422-36: Correctly program MCVP 3D mode based on source and display
177 * orientation
178 *
179 * Hydra_Software_Devel/428   11/12/10 3:56p pntruong
180 * SW7425-31: Takes bvn yuv into account for hddvi input.  Fixed bad debug
181 * register read on non-mfd source.  Updated scratch registers
182 * availabliity.
183 *
184 * Hydra_Software_Devel/427   11/11/10 7:30p albertl
185 * SW7125-364: Fixed BVDC_P_CbIsDirty and added assert to check bitfields
186 * in dirty bits fit within union integer representation.  Fixed naming
187 * of dirty bits.
188 *
189 * Hydra_Software_Devel/426   11/11/10 7:12p hongtaoz
190 * SW7425-51: reduced combo trigger use in VDC to 1 per MFD source;
191 *
192 * Hydra_Software_Devel/425   10/29/10 10:58a yuxiaz
193 * SW7422-31, SW7422-32, SW7422-39: More for 3D Video support.
194 *
195 * Hydra_Software_Devel/424   10/11/10 12:43p jessem
196 * SW7420-173: Added support for VFD as source feature.
197 *
198 * Hydra_Software_Devel/423   9/21/10 6:10p yuxiaz
199 * SW7422-31, SW7422-32: Handle single and dual buffer 3D cases in MFD.
200 *
201 * Hydra_Software_Devel/422   8/31/10 5:00p yuxiaz
202 * SW7422-39: Clean up feeder programming.
203 *
204 * Hydra_Software_Devel/421   6/18/10 4:23p rpan
205 * SW7400-2763: New BVN resource management.
206 *
207 * Hydra_Software_Devel/420   5/7/10 7:20p albertl
208 * SW7125-364: Changed dirty bits to use union structure to avoid type-pun
209 * warnings
210 *
211 * Hydra_Software_Devel/419   5/3/10 4:57p syang
212 * SW7405-4239: 1). use uint64_t for aspect ratio numbers; 2). avoid even
213 * pixel rounding before aspect ratio correction calculation
214 *
215 * Hydra_Software_Devel/418   4/23/10 6:00p tdo
216 * SW7401-3828: Support AFD=2, 3 for asia market. Add the AFD clipping for
217 * SAR that has equivalent DAR of 4x3 and 16x9.
218 *
219 * Hydra_Software_Devel/417   4/19/10 10:20p tdo
220 * SW3548-2814: Improvements to VDC ulBlackMagic. Move
221 * BDBG_OBJECT_ID_DECLARE private header files instead of .c.
222 *
223 * Hydra_Software_Devel/416   4/8/10 2:09p syang
224 * SW7405-4090: in non-mosaic mode case need to initMute only if
225 * picChanged
226 *
227 * Hydra_Software_Devel/415   4/7/10 11:35a tdo
228 * SW3548-2814: Improvements to VDC ulBlackMagic.  Rename TLA
229 *
230 * Hydra_Software_Devel/414   4/6/10 2:12p tdo
231 * SW3548-2814: Improvements to VDC ulBlackMagic. Fix window timeout issue
232 *
233 * Hydra_Software_Devel/413   4/5/10 4:13p tdo
234 * SW3548-2814: Improvements to VDC ulBlackMagic
235 *
236 * Hydra_Software_Devel/412   4/2/10 2:57p yuxiaz
237 * SW7405-3965: Mosaic decoder can't be attached to the window of the 2nd
238 * display.
239 *
240 * Hydra_Software_Devel/411   4/1/10 4:48p syang
241 * SW7405-4090: avoid to use prev mosaic rect data in muted case
242 *
243 * Hydra_Software_Devel/410   3/17/10 12:04p syang
244 * SW7405-4046: set canvas ctrl after sur ctrl; handle gfx win vnet the
245 * same as video; ensure that reader and writer vnetState match in sync-
246 * locked case; aligned width up to even for stride in feeder and cap;
247 * assert mosaic mode doesn't co-exist with dest cut;
248 *
249 * Hydra_Software_Devel/409   12/23/09 1:13p yuxiaz
250 * SW7405-3670: Source callback doesn't work correctly for MPEG source.
251 *
252 * Hydra_Software_Devel/408   12/22/09 5:16p tdo
253 * SW7401-3828: Add AFD support
254 *
255 * Hydra_Software_Devel/407   12/22/09 4:02p syang
256 * SW7550-143: fix coverity complain
257 *
258 * Hydra_Software_Devel/406   12/18/09 10:29a yuxiaz
259 * SW7405-3633: Fix Coverity warings in VDC
260 *
261 * Hydra_Software_Devel/405   12/2/09 3:04p yuxiaz
262 * SW7405-3120: Added support for overlapping mosaic videos with z-
263 * ordering
264 *
265 * Hydra_Software_Devel/404   11/17/09 10:00p pntruong
266 * SW3556-866: Expose vdec frontend csc for adc calibration for scart
267 * input.
268 *
269 * Hydra_Software_Devel/403   11/16/09 5:03p yuxiaz
270 * SW7405-3406: Clean up bMosaicMode and  bMosaicClearOutside.
271 *
272 * Hydra_Software_Devel/402   11/6/09 3:28p yuxiaz
273 * SW7420-117: Added support for Newer Chroma Sample Location Types.
274 *
275 * Hydra_Software_Devel/401   10/22/09 6:20p hongtaoz
276 * SW7405-3280: always update source picture context;
277 *
278 * Hydra_Software_Devel/400   10/22/09 2:23p yuxiaz
279 * SW7405-3200: Destroy PIP window causes momentary flashes on the display
280 * in mosaic mode.
281 *
282 * Hydra_Software_Devel/399   10/5/09 3:21p tdo
283 * SW7405-3044:align H&V size in Mpeg source data ready so that it can be
284 * consistent downstream
285 *
286 * Hydra_Software_Devel/398   6/2/09 3:03p syang
287 * PR 55646:  smoothly filtering  in field inversion cases
288 *
289 * Hydra_Software_Devel/397   5/28/09 2:19p yuxiaz
290 * PR55364: Disable dithering when any testfeature1 is enabled
291 *
292 * Hydra_Software_Devel/396   5/20/09 7:31p pntruong
293 * PR53654: Make for format change msg consistence for ease of debugging
294 * memory allocation.
295 *
296 * Hydra_Software_Devel/395   4/24/09 9:09a syang
297 * PR 54557:  avoid src_isr to build ShutDownRul before disp_isr cleanUp
298 * src slots
299 *
300 * Hydra_Software_Devel/394   4/17/09 11:56a pntruong
301 * PR54064: Refactored common code for defered callback til bvn shutdown.
302 * Improved readability and extensibility of dirty bits.
303 *
304 * Hydra_Software_Devel/393   4/10/09 6:28p hongtaoz
305 * PR54064: source pending callback must fire after window shutdown;
306 *
307 * Hydra_Software_Devel/392   4/3/09 4:34p yuxiaz
308 * PR53460: Optimal 444/422 conversion settings
309 *
310 * Hydra_Software_Devel/391   3/30/09 4:12p rpan
311 * PR53677: Add support for XVD NTSC->PAL frame drop mode.
312 *
313 * Hydra_Software_Devel/390   3/16/09 10:50p tdo
314 * PR45785, PR45789: Merge from MCVP branch
315 *
316 * Hydra_Software_Devel/7420_mcvp/4   3/16/09 1:02p tdo
317 * PR45785, PR45789: merge from main branch on 3/16/09
318 *
319 * Hydra_Software_Devel/389   3/13/09 5:29p syang
320 * PR 52376, PR 41481, PR 44041:
321 * 1). exec user buf returning to hBuffer before shut-down code in
322 * writer_isr; 2). clean up mad-delay handling code and add handling to
323 * all settings in pic-node that are delayed by mad; 3). 444 SCL no-
324 * longer uses BVN_IN to align-up for half-band; 4). add pic-node rects
325 * dump feature as setting lbox_0_scratch to 2 (1 still printing mpeg pic
326 * info).
327 *
328 * Hydra_Software_Devel/7420_mcvp/3   3/2/09 4:21p tdo
329 * PR 45785, PR 45789: merge from main branch on 3/02/09
330 *
331 * Hydra_Software_Devel/388   3/2/09 3:46p yuxiaz
332 * PR52287: More update on 422-444 and 444-422 converters.
333 *
334 * Hydra_Software_Devel/7420_mcvp/2   2/5/09 9:53a syang
335 * PR 45785, PR 45789:   get rid of BVDC_Source_Get/SetAnrConfiguration
336 *
337 * Hydra_Software_Devel/7420_mcvp/1   1/23/09 11:31p syang
338 * PR 45785, PR 45789: add PI support for new the new module  MCVP
339 * (MCTF+MCDI)
340 *
341 * Hydra_Software_Devel/387   1/5/09 8:23p pntruong
342 * PR50722, PR50724: Improve the speed of RGB input auto phase adjustment.
343 *
344 * Hydra_Software_Devel/PR50722/1   12/29/08 12:34p gorgon
345 * PR50724: Improve the speed of RGB input auto phase adjustment.
346 *
347 * Hydra_Software_Devel/386   12/4/08 5:23p pntruong
348 * PR50002: VDC: Added function to force source pending.
349 *
350 * Hydra_Software_Devel/385   12/1/08 7:50p pntruong
351 * PR49391, PR49398: Initialized get storage to avoid unitialized usage.
352 *
353 * Hydra_Software_Devel/384   11/24/08 3:34p albertl
354 * PR49393: Fixed unused value coverity warning
355 *
356 * Hydra_Software_Devel/383   11/10/08 5:01p syang
357 * PR 41898: remove un-needed bools from win-context and dirty bits
358 *
359 * Hydra_Software_Devel/382   11/7/08 5:24p albertl
360 * PR48740: Fixed compiler warnings when debug is turned off.
361 *
362 * Hydra_Software_Devel/381   10/25/08 1:29p pntruong
363 * PR47747: Added ability to bypass adc common mode.
364 *
365 * Hydra_Software_Devel/380   10/3/08 3:34p syang
366 * PR 45751:  no need to send src-pending callback if pic changes from un-
367 * muted to muted
368 *
369 * Hydra_Software_Devel/379   10/3/08 12:21p syang
370 * pr 47129, pr 45402 :  1). improve  the VDC internally used videoFmtCode
371 * approximate; 2). return w, h, frmRate and bInterlaced with src-pending
372 * callback for non-enumerated mpeg-src video format
373 *
374 * Hydra_Software_Devel/378   9/26/08 1:32p pntruong
375 * PR46515: Adapted to new power management.
376 *
377 * Hydra_Software_Devel/377   9/26/08 11:49a syang
378 * PR45751: PR43944: send out source pending callback when mpeg field mute
379 * status change
380 *
381 * Hydra_Software_Devel/PR45751/1   9/16/08 8:33p mlei
382 * PR43944: send out source pending callback when mpeg field mute status
383 * change
384 *
385 * Hydra_Software_Devel/376   8/28/08 5:44p pntruong
386 * PR46252: Need to expose 444 format in static buffers case.  Localize
387 * the validity of pixel in feeder.
388 *
389 * Hydra_Software_Devel/375   8/21/08 6:20p pntruong
390 * PR45830: Allowed the 1080p feeding for jpg thru mfd.
391 *
392 * Hydra_Software_Devel/374   8/12/08 9:31p pntruong
393 * PR45566: Added support for standard (legacy) mode of combing.
394 *
395 * Hydra_Software_Devel/373   7/11/08 11:32a yuxiaz
396 * PR44072, PR43785: Clear callback dirty bits.
397 *
398 * Hydra_Software_Devel/372   7/10/08 10:49a pntruong
399 * PR40213: Corrected the bHVStartOverride it must be set thru the
400 * BVDC_Source_SetHVStart API.
401 *
402 * Hydra_Software_Devel/371   7/2/08 10:51a yuxiaz
403 * PR44072, PR43785: Do not adjust original source size if requested to
404 * capture CRC.
405 *
406 * Hydra_Software_Devel/370   6/27/08 1:41p yuxiaz
407 * PR43785: Combine source pending and CRC callback into one.
408 *
409 * Hydra_Software_Devel/369   6/24/08 4:20p syang
410 * PR35549, PR44050:  1).  fire gen-callbck for format change even if not
411 * src-pending;   2).  allow callbck even if NULL pic for jpeg pic
412 * display
413 *
414 * Hydra_Software_Devel/368   6/22/08 9:42a pntruong
415 * PR40213: Fine tune settings for PC raster adjustment.
416 *
417 * Hydra_Software_Devel/367   6/20/08 3:43p tdo
418 * PR43662 , PR43645, PR38841: Fix mosaic and SD to HD channel change due
419 * to adjust rectangle being ignored when picture is muted.
420 *
421 * Hydra_Software_Devel/366   6/18/08 3:05p syang
422 * PR35549: 1). src-pending when new win is created; 2). don't do
423 * BufferHeap_AllocateBuffers as bReConfigSrc
424 *
425 * Hydra_Software_Devel/365   6/14/08 4:00p syang
426 * PR35549:  added src-pending callback for mpeg src
427 *
428 * Hydra_Software_Devel/364   5/30/08 1:37p tdo
429 * PR38362, PR38678, PR38841, PR38842: More fine tuning of the BVN HW
430 * limitation implementation.
431 *
432 * Hydra_Software_Devel/363   5/29/08 1:30p tdo
433 * PR38362, PR38678, PR38841, PR38842: Enforce Hardware Minimum Size
434 * Limitation for BVN Blocks and Partition Between Destination and Source
435 * Clipping To Support 2x1 Window Size
436 *
437 * Hydra_Software_Devel/362   5/13/08 3:35p jessem
438 * PR 39456: Added big endian check for valid pixel formats in
439 * BVDC_P_Source_ValidateMpegData_isr. Also, removed muting of picture if
440 * pixel format is invalid. If invalid, a green and pink picture will
441 * result alerting the user that the pixel format used is not supported.
442 *
443 * Hydra_Software_Devel/361   5/8/08 5:54p pntruong
444 * PR35549: Added more preparations for source pending.
445 *
446 * Hydra_Software_Devel/360   4/21/08 4:34p hongtaoz
447 * PR35398, PR40895: some compiler might generate floating point
448 * instructions;
449 *
450 * Hydra_Software_Devel/359   4/3/08 1:47p tdo
451 * PR38771, PR38777, PR39246: all chips with DNR are supporting DCR now,
452 * remove unnecessary check for DCR
453 *
454 * Hydra_Software_Devel/358   4/1/08 5:24p pntruong
455 * PR41124: [vdc]: Add an api to get source default h/v start.
456 *
457 * Hydra_Software_Devel/357   3/26/08 1:15p hongtaoz
458 * PR35398, PR40895: added ulVsyncRate and removed bGameModeDelayLags in
459 * the window lipsync callback structure; added BFMT_FREQ_FACTOR to unify
460 * Vsync rate and pixel frequency calculation;
461 *
462 * Hydra_Software_Devel/356   3/25/08 3:17p syang
463 * PR 40431: add complete assert for critical section protection among src
464 * _isr, dsp _isr, and ApplyChanges
465 *
466 * Hydra_Software_Devel/355   3/19/08 5:28p pntruong
467 * PR38442: Updated BVDC_Source_SetAdcConfiguration so that only set dirty
468 * bit on change is detected, and set bAdcSetting dirty bit.  This dirty
469 * bit will re-initialize vdec internal state machine, and briefly mute
470 * video.
471 *
472 * Hydra_Software_Devel/354   3/17/08 5:49p pntruong
473 * PR39162: Added stub api for documentation.
474 *
475 * Hydra_Software_Devel/353   3/3/08 4:47p pntruong
476 * PR40201: Added better default for choosing interlaced/progressived.
477 *
478 * Hydra_Software_Devel/352   3/3/08 4:11p yuxiaz
479 * PR40201: VDC has bad BDBG_WRN which causes intermittent crash
480 *
481 * Hydra_Software_Devel/351   2/26/08 4:48p jessem
482 * PR 34590, PR 39456: Removed ENDIAN treatment of pixel format of
483 * pNewPic->hSurface in BVDC_P_Source_ValidateMpegData_isr.
484 *
485 * Hydra_Software_Devel/350   2/21/08 5:01p pntruong
486 * PR39244: Need drain debugging hooked up to HD_DVI, VDEC, and 656in.
487 * Improved code readability.
488 *
489 * Hydra_Software_Devel/349   2/15/08 2:33p yuxiaz
490 * PR34712, PR39251: Use feeder version to combine all the feeder flags.
491 * Regroup feeder support based on feeder version.
492 *
493 * Hydra_Software_Devel/348   2/12/08 7:43p tdo
494 * PR38771, PR38777, PR39246: Implement changes for DNR/DCR cores for 3548
495 *
496 * Hydra_Software_Devel/347   2/4/08 6:13p pntruong
497 * PR39317: Correctly search for 288p and 240p.
498 *
499 * Hydra_Software_Devel/346   1/24/08 5:10p pntruong
500 * PR38832: Video decoding and display (noise stream) failed in customer's
501 * QA testing.  Need ensure parameters from decoder to mfd is valid.
502 *
503 * Hydra_Software_Devel/345   1/22/08 11:51a pntruong
504 * PR38657:  Relax format mapping to only scantype and height.
505 *
506 * Hydra_Software_Devel/344   1/21/08 3:42p pntruong
507 * PR38657: 576p video blinking problem with Phase5.0 take2.  Identify
508 * correct source information to determine correct cappture buffer size.
509 *
510 * Hydra_Software_Devel/343   11/15/07 3:53p yuxiaz
511 * PR34523: 7325 bring up.
512 *
513 * Hydra_Software_Devel/342   11/14/07 10:55a rpan
514 * PR31084: Consider NULL pointers as valid values when getting
515 * VDEC/Deinterlace default settings.
516 *
517 * Hydra_Software_Devel/341   11/13/07 5:34p rpan
518 * PR31084: Added support for getting VDEC default settings.
519 *
520 * Hydra_Software_Devel/340   10/30/07 7:24p pntruong
521 * PR34239: Allow dynamically loading of vec custom timing.
522 *
523 * Hydra_Software_Devel/339   10/23/07 11:17a yuxiaz
524 * PR29569, PR36290: Add FGT support on 7405.
525 *
526 * Hydra_Software_Devel/PR29569/3   10/19/07 11:31a yuxiaz
527 * PR29569: Merge from mainline.
528 *
529 * Hydra_Software_Devel/338   10/19/07 8:33a pntruong
530 * PR36256: [VDEC][PC]:Ensure the H positon is right when finding new
531 * format, adjusting manua phase and adjusting manual clock.
532 *
533 * Hydra_Software_Devel/Gorgon_temp_20071019/1   10/19/07 2:56p gorgon
534 * PR36256:[VDEC][PC]:Ensure the H positon is right when finding new
535 * format, adjusting manua phase and adjusting manual clock.
536 *
537 * Hydra_Software_Devel/337   10/18/07 12:05a pntruong
538 * PR36137: [PC]:Set pc input video format without disable auto format
539 * detection.
540 *
541 * Hydra_Software_Devel/336   10/16/07 2:56p hongtaoz
542 * PR34955: enforce 1080p condition for PsF feature; restore source
543 * vertical freq when DM starts non-1080p picture, to avoid sync-slipped
544 * multi-buffer bouncing due to rate gap;
545 *
546 * Hydra_Software_Devel/335   10/11/07 2:09p albertl
547 * PR35135:  Fixed user csc macros and added 10-bit/8-bit video data
548 * conversion.
549 *
550 * Hydra_Software_Devel/334   10/4/07 4:15p pntruong
551 * PR35412: Clearout pointers for gets as specified in api.
552 *
553 * Hydra_Software_Devel/333   10/3/07 4:53p pntruong
554 * PR35412: Expose API to enable/Disable of Coring
555 * (VDEC_BE_0_DITHER_CORING_ENABLE).
556 *
557 * Hydra_Software_Devel/332   10/2/07 11:25a pntruong
558 * PR35136: Some cleanup of unused code.
559 *
560 * Hydra_Software_Devel/331   9/23/07 3:38p hongtaoz
561 * PR34955: added 1080p PsF support for PIP mpg source; fixed debug
562 * message error;
563 *
564 * Hydra_Software_Devel/330   9/21/07 3:59p hongtaoz
565 * PR34955: added Progressive Segmented Frame(PsF) 1080p support; fixed
566 * 1080p pass-through condition; fixed bvdc_dbg register access error;
567 * fixed general progressive capture interlaced playback feeder
568 * programming problem;
569 *
570 * Hydra_Software_Devel/329   9/20/07 1:53a albertl
571 * PR34966:  Added 7440 to 1080p MFD support macro.
572 *
573 * Hydra_Software_Devel/328   9/20/07 1:21a albertl
574 * PR35135:  Cleaned up color space matrices and changed them to use same
575 * macro system.  Added color space conversion functionality to graphics
576 * windows.
577 *
578 * Hydra_Software_Devel/327   9/12/07 3:24p rpan
579 * PR 34144: Added 7400 to 1080p support list
580 *
581 * Hydra_Software_Devel/326   9/12/07 11:28a rpan
582 * PR 34144: Allow 1080p mpeg src to pass through vdc pipe line as 1080p.
583 *
584 * Hydra_Software_Devel/326   9/12/07 11:25a rpan
585 * PR 34144: Allow 1080p mpeg src to pass through vdc pipe line as 1080p.
586 *
587 * Hydra_Software_Devel/326   9/12/07 10:56a rpan
588 * PR 34144: allow 1080p mpeg src to pass through vdc pipe line as 1080p.
589 *
590 * Hydra_Software_Devel/325   9/10/07 1:55p pntruong
591 * PR34690: [PC]:Smooth the performance of manual clock. Toggle the
592 * H_threshold when manual clock to make sure the position accurate.
593 *
594 * Hydra_Software_Devel/PR34690/1   9/10/07 8:58p gorgon
595 * PR34690:[PC]:Smooth the performance of manual clock. Toggle the
596 * H_threshold when manual clock to make sure the position accurate.
597 *
598 * Hydra_Software_Devel/324   8/6/07 11:08a pntruong
599 * PR33348: Identify mpeg format of hd/sd/ed with curinfo->pfmt.
600 *
601 * Hydra_Software_Devel/323   7/31/07 10:12p pntruong
602 * PR33634: ANR assert when turning off MAD and switching progressive mpeg
603 * source to interlaced mpeg source.
604 *
605 * Hydra_Software_Devel/322   7/26/07 6:27p pntruong
606 * PR33427:  Need to trigger aspect ratio computation when panscan widnow
607 * size changes.
608 *
609 * Hydra_Software_Devel/321   7/23/07 10:14a pntruong
610 * PR31869: [VDEC] snow noise blink between normal snow noise and black
611 * screen.
612 *
613 * Hydra_Software_Devel/320   7/19/07 2:37p tdo
614 * PR33034: Modify DNR API to extend MNR/BNR/DCR filter level
615 *
616 * Hydra_Software_Devel/319   7/9/07 3:48p pntruong
617 * PR32775: Hstart user setting is overwritten in VDEC.
618 *
619 * Hydra_Software_Devel/318   6/27/07 1:46p pntruong
620 * PR32503: Cleanup unused code.  Prepare for 480i/480p vdec oversample.
621 *
622 * Hydra_Software_Devel/317   6/27/07 12:32p tdo
623 * PR32489: Add support for custom adjust DNR
624 *
625 * Hydra_Software_Devel/316   6/26/07 5:37p pntruong
626 * PR32402: TV display "unsupport format" and "no signal" OSD for
627 * componet/hdmi input.
628 *
629 * Hydra_Software_Devel/315   6/21/07 7:39p pntruong
630 * PR30427: Allow blackoffset to be custom even for component input.
631 *
632 * Hydra_Software_Devel/314   6/21/07 3:38p syang
633 * PR 32440: clean up inefficient "if" statement
634 *
635 * Hydra_Software_Devel/313   6/21/07 2:17p yuxiaz
636 * PR32023: Added video format tolerance to HDDVI.
637 *
638 * Hydra_Software_Devel/312   6/14/07 7:30p pntruong
639 * PR31977: [VDEC]Auto detection for PAL can not work well when user
640 * toggle auto/manual mode.
641 *
642 * Hydra_Software_Devel/311   6/13/07 2:25p hongtaoz
643 * PR28019: downgrade message level for the invalid eYCbCr type to avoid
644 * flooding the terminal before decode;
645 *
646 * Hydra_Software_Devel/310   6/13/07 9:45a syang
647 * PR 31944: put ANR K value table inro seperate file; change to use
648 * SnDbAdj from 5 level adj
649 *
650 * Hydra_Software_Devel/309   6/11/07 7:25p tdo
651 * PR31947: provide API to allow user setting the Qp value for DNR
652 *
653 * Hydra_Software_Devel/308   6/6/07 2:01p yuxiaz
654 * PR30015: Use stripe width from XVD.
655 *
656 * Hydra_Software_Devel/307   5/31/07 1:43p yuxiaz
657 * PR30015: Added support in VDC to accept strip width as input parameter
658 * from XVD.
659 *
660 * Hydra_Software_Devel/306   5/16/07 11:15a pntruong
661 * PR30361: Provide API to control DC restore.
662 *
663 * Hydra_Software_Devel/305   5/15/07 11:47a yuxiaz
664 * PR29940: Add support to set and get Hstart and Vstart for HDDVI.
665 *
666 * Hydra_Software_Devel/304   5/14/07 7:07p pntruong
667 * PR30360: Provide API to customer VDEC YCbCr delay.
668 *
669 * Hydra_Software_Devel/303   5/14/07 3:05p hongtaoz
670 * PR30307: DM should not send toggling frame/field to VDC once started;
671 *
672 * Hydra_Software_Devel/302   5/14/07 2:01p pntruong
673 * PR30363: Provide API to enable/disable ACGC.
674 *
675 * Hydra_Software_Devel/301   5/14/07 1:13p pntruong
676 * PR30427: Intialized black offset for vdec.
677 *
678 * Hydra_Software_Devel/300   5/14/07 11:40a pntruong
679 * PR30427: Provide API to control black offset in VDEC.
680 *
681 * Hydra_Software_Devel/299   5/10/07 9:59a syang
682 * PR 28895, PR 28898, PR 29846 , PR 28550: 1). add frame for C0 ANR PI
683 * support; 2). move MAD/ANR buf alloc/free to MAD/ANR; 3). remove
684 * drainVnet state
685 *
686 * Hydra_Software_Devel/298   4/19/07 1:48p yuxiaz
687 * PR 26052: Add CSC support in MFD on 7400 B0.
688 *
689 * Hydra_Software_Devel/297   4/12/07 5:01p albertl
690 * PR28019:  BVDC_Source_MpegDataReady_isr no longer modifies pvMvdField
691 * and now uses local copy.
692 *
693 * Hydra_Software_Devel/296   4/9/07 11:25a pntruong
694 * PR28266: Provide API to customize DVO CSC.
695 *
696 * Hydra_Software_Devel/295   4/6/07 9:49a pntruong
697 * PR29555: Support feeding 1080p JPEG image from MFD.
698 *
699 * Hydra_Software_Devel/294   4/5/07 11:25p pntruong
700 * PR28395, PR28538, PR28539, PR28540: Vdec customizations, and
701 * deinterlacer customizations.
702 *
703 * Hydra_Software_Devel/293   4/5/07 9:23a syang
704 * PR 27611: allow  ANR on digital src, DNR on analog src, and ANR and DNR
705 * used together
706 *
707 * Hydra_Software_Devel/292   4/2/07 11:31a syang
708 * PR 29243: clean up: take off the obselete old-vnet-code
709 *
710 * Hydra_Software_Devel/291   3/30/07 10:41a yuxiaz
711 * PR28350, PR27180: Added BVDC_Source_GetInputStatus to get input status
712 * for VDEC and HD_DVI.
713 *
714 ***************************************************************************/
715#include "bstd.h"              /* standard types */
716#include "bkni.h"              /* memcpy calls */
717#include "bvdc.h"              /* Video display */
718#include "bvdc_common_priv.h"
719#include "bvdc_priv.h"
720#include "bvdc_dnr_priv.h"
721#include "bvdc_feeder_priv.h"
722#include "bvdc_capture_priv.h"
723#include "bvdc_source_priv.h"
724#include "bvdc_window_priv.h"
725#include "bvdc_compositor_priv.h"
726#include "bvdc_display_priv.h"
727#include "bvdc_displayfmt_priv.h"
728#include "bvdc_vnet_priv.h"
729#include "bvdc_hddvi_priv.h"
730#include "bvdc_vdec_priv.h"
731#include "bvdc_downsample_priv.h"
732#include "bchp_int_id_bvnf_intr2_0.h"
733
734BDBG_MODULE(BVDC_SRC);
735
736
737/* How to map mpeg format to BFMT format. */
738static const BFMT_VideoFmt s_aeMpegToFmt[] =
739{
740        BFMT_VideoFmt_eNTSC,
741        BFMT_VideoFmt_ePAL_G,
742        BFMT_VideoFmt_e480p,
743        BFMT_VideoFmt_e576p_50Hz,
744        BFMT_VideoFmt_e720p,
745        BFMT_VideoFmt_e720p_50Hz,
746        BFMT_VideoFmt_e1080i,
747        BFMT_VideoFmt_e1080i_50Hz,
748        BFMT_VideoFmt_e1080p,
749        BFMT_VideoFmt_e1080p_24Hz,
750        BFMT_VideoFmt_e1080p_25Hz,
751        BFMT_VideoFmt_e1080p_30Hz,
752        BFMT_VideoFmt_e1080p_50Hz,
753        BFMT_VideoFmt_ePAL_60,
754        BFMT_VideoFmt_e720p_24Hz,
755
756        /* */
757        BFMT_VideoFmt_e1250i_50Hz,
758        BFMT_VideoFmt_e240p_60Hz,
759        BFMT_VideoFmt_e288p_50Hz
760};
761
762static const uint32_t s_aulFrmRate[] =
763{
764        0,     /*BAVC_FrameRateCode_eUnknown = 0,*/
765        2397,  /*BAVC_FrameRateCode_e23_976 = 1,*/
766        2400,  /*BAVC_FrameRateCode_e24        ,*/
767        2500,  /*BAVC_FrameRateCode_e25        ,*/
768        2997,  /*BAVC_FrameRateCode_e29_97     ,*/
769        3000,  /*BAVC_FrameRateCode_e30        ,*/
770        5000,  /*BAVC_FrameRateCode_e50        ,*/
771        5994,  /*BAVC_FrameRateCode_e59_94     ,*/
772        6000   /*BAVC_FrameRateCode_e60         */
773};
774
775#define BVDC_P_MPEG_FMT_DELTA                 (16) /* detal for matching */
776#define BVDC_P_MPEG_FMT_COUNT                 (sizeof(s_aeMpegToFmt)/sizeof(BFMT_VideoFmt))
777#define BVDC_P_MAX_FRM_RATE_CODE              (sizeof(s_aulFrmRate)/sizeof(uint32_t) -1)
778
779/* PsF: 30Hz is the max PsF scanout frequency (x100 to follow FMT style); */
780#define BVDC_P_PSF_VERT_FREQ                     (30 * BFMT_FREQ_FACTOR)
781
782/***************************************************************************
783 *
784 */
785BERR_Code BVDC_Source_GetDefaultSettings
786        ( BAVC_SourceId                    eSourceId,
787          BVDC_Source_Settings            *pDefSettings )
788{
789        BSTD_UNUSED(eSourceId);
790
791        /* To make sure thing get initialize */
792        BKNI_Memset(pDefSettings, 0, sizeof(*pDefSettings));
793
794        /* TODO: double check the default settings */
795        pDefSettings->hHeap        = NULL;
796        pDefSettings->eDsSrcCompId = BVDC_CompositorId_eCompositor0;
797
798        return BERR_SUCCESS;
799}
800
801/***************************************************************************
802 *
803 */
804BERR_Code BVDC_Source_Create
805        ( BVDC_Handle                      hVdc,
806          BVDC_Source_Handle              *phSource,
807          BAVC_SourceId                    eSourceId,
808          const BVDC_Source_Settings      *pDefSettings )
809{
810        BVDC_P_SourceContext *pSource;
811        BVDC_P_DrainContext stTmpDrain;
812
813        BDBG_ENTER(BVDC_Source_Create);
814        BDBG_ASSERT(phSource);
815        BDBG_OBJECT_ASSERT(hVdc, BVDC_VDC);
816
817        BKNI_Memset((void*)&stTmpDrain, 0x0, sizeof(BVDC_P_DrainContext));
818
819        /* Making sure features is available. */
820        if(!hVdc->pFeatures->abAvailSrc[eSourceId])
821        {
822                BDBG_ERR(("Source[%d] not supported on this chipset.", eSourceId));
823                return BERR_TRACE(BERR_NOT_SUPPORTED);
824        }
825
826        /* Find an available drain for the source. */
827        if( BVDC_P_SRC_NEED_DRAIN(eSourceId))
828        {
829                if(BVDC_P_Drain_Acquire(&stTmpDrain, hVdc->hResource, eSourceId) != BERR_SUCCESS)
830                {
831                        BDBG_ERR(("No Vnet drain available for Source[%d]", eSourceId));
832                        BDBG_ERR(("Source[%d] not supported on this chipset.", eSourceId));
833                        return BERR_TRACE(BERR_NOT_SUPPORTED);
834                }
835        }
836
837        pSource = hVdc->ahSource[eSourceId];
838        BDBG_OBJECT_ASSERT(pSource, BVDC_SRC);
839        pSource->stDrain = stTmpDrain;
840
841        if(BVDC_P_SRC_IS_DS(eSourceId))
842        {
843                BVDC_P_CompositorContext *pDsCompositor;
844
845                pSource->eDsSrcCompId = (pDefSettings)
846                        ? pDefSettings->eDsSrcCompId : BVDC_CompositorId_eCompositor0;
847
848                pDsCompositor = hVdc->ahCompositor[pSource->eDsSrcCompId];
849
850                if(pDsCompositor->eState != BVDC_P_State_eActive)
851                {
852                        BDBG_ERR(("Source compositor must be open before opening downsample source."));
853                        return BERR_INVALID_PARAMETER;
854                }
855        }
856
857        /* Check if source is created or not. */
858        if(BVDC_P_STATE_IS_ACTIVE(pSource) ||
859           BVDC_P_STATE_IS_CREATE(pSource) ||
860           BVDC_P_STATE_IS_DESTROY(pSource))
861        {
862                return BERR_TRACE(BVDC_ERR_SOURCE_ALREADY_CREATED);
863        }
864
865        BDBG_MSG(("Creating source%d", pSource->eId));
866        BDBG_ASSERT(BVDC_P_STATE_IS_INACTIVE(pSource));
867
868        /* Reinitialize context.  But not make it active until apply. */
869        *phSource = pSource;
870
871        /* Which heap to use? */
872        pSource->hHeap = ((pDefSettings) && (pDefSettings->hHeap))
873                ? pDefSettings->hHeap : hVdc->hBufferHeap;
874
875        BVDC_P_Source_Init(*phSource);
876
877        /* Mark as create, awating for apply. */
878        pSource->eState = BVDC_P_State_eCreate;
879
880        BDBG_LEAVE(BVDC_Source_Create);
881        return BERR_SUCCESS;
882}
883
884
885/***************************************************************************
886 *
887 */
888BERR_Code BVDC_Source_Destroy
889        ( BVDC_Source_Handle               hSource )
890{
891        int i;
892
893        BDBG_ENTER(BVDC_Source_Destroy);
894        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
895
896        /* Check to see if there are any active windows that's still using
897         * this source. */
898        for(i = 0; i < BVDC_P_MAX_WINDOW_COUNT; i++)
899        {
900                if(BVDC_P_STATE_IS_ACTIVE(hSource->ahWindow[i]))
901                {
902                        BDBG_ERR(("Window %d is still using this source.", hSource->ahWindow[i]->eId));
903                        BDBG_ERR(("The window state is %d.", hSource->ahWindow[i]->eState));
904                        return BERR_TRACE(BERR_LEAKED_RESOURCE);
905                }
906        }
907
908        /* Release the drain for the source. */
909        if(BVDC_P_SRC_NEED_DRAIN(hSource->eId))
910        {
911                BVDC_P_Drain_Release(&hSource->stDrain, hSource->hVdc->hResource);
912        }
913
914        /* Disconnect source compositor from DS. */
915        if( BVDC_P_SRC_IS_DS(hSource->eId) )
916        {
917                BVDC_P_DownSample_Disconnect(hSource->hDownSample);
918                BDBG_MSG(("Src[%d] disconnected from source compositor %d", hSource->eDsSrcCompId));
919        }
920
921        if(BVDC_P_STATE_IS_DESTROY(hSource) ||
922           BVDC_P_STATE_IS_INACTIVE(hSource))
923        {
924                goto done;
925        }
926
927        if(BVDC_P_STATE_IS_ACTIVE(hSource) ||
928           BVDC_P_STATE_IS_CREATE(hSource))
929        {
930                hSource->eState = BVDC_P_State_eDestroy;
931        }
932
933done:
934        BDBG_LEAVE(BVDC_Source_Destroy);
935        return BERR_SUCCESS;
936}
937
938
939/***************************************************************************
940 *
941 */
942BERR_Code BVDC_Source_GetSize
943        ( const BVDC_Source_Handle         hSource,
944          uint32_t                        *pulWidth,
945          uint32_t                        *pulHeight )
946{
947        const BFMT_VideoInfo *pFmtInfo;
948        uint32_t ulWidth  = 0;
949        uint32_t ulHeight = 0;
950
951        BDBG_ENTER(BVDC_Source_GetSize);
952        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
953
954        /* Analog/656 we know the source size, but for mpeg the source size
955         * can change dynamically (dynamic source picture change).   Hence
956         * we can only return the size of analog or 656 source. */
957        if(BVDC_P_SRC_IS_ANALOG(hSource->eId) ||
958           BVDC_P_SRC_IS_ITU656(hSource->eId))
959        {
960                pFmtInfo = hSource->stCurInfo.pFmtInfo;
961                ulWidth  = pFmtInfo->ulWidth;
962                ulHeight = pFmtInfo->ulHeight;
963        }
964        else if(BVDC_P_SRC_IS_MPEG(hSource->eId) ||
965                BVDC_P_SRC_IS_HDDVI(hSource->eId))
966        {
967                BKNI_EnterCriticalSection();
968                ulWidth  = hSource->stExtVideoFmtInfo.ulWidth;
969                ulHeight = hSource->stExtVideoFmtInfo.ulHeight;
970                BKNI_LeaveCriticalSection();
971        }
972
973        if(pulWidth)
974        {
975                *pulWidth = ulWidth;
976        }
977
978        if(pulHeight)
979        {
980                *pulHeight = ulHeight;
981        }
982
983        BDBG_LEAVE(BVDC_Source_GetSize);
984        return BERR_SUCCESS;
985}
986
987
988/***************************************************************************
989 *
990 */
991BERR_Code BVDC_Source_SetVideoFormat
992        ( BVDC_Source_Handle               hSource,
993          BFMT_VideoFmt                    eVideoFmt )
994{
995        BVDC_P_Source_Info *pNewInfo;
996
997        BDBG_ENTER(BVDC_Source_SetVideoFormat);
998        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
999
1000        pNewInfo  = &hSource->stNewInfo;
1001
1002        /* Restricted to only supported format. */
1003        if(BVDC_P_SRC_IS_ITU656(hSource->eId))
1004        {
1005                /* 656 specific validation. */
1006                if(!VIDEO_FORMAT_IS_PAL(eVideoFmt) &&
1007                   !VIDEO_FORMAT_IS_NTSC(eVideoFmt))
1008                {
1009                        return BERR_TRACE(BVDC_ERR_VIDEO_FORMAT_NOT_SUPPORTED);
1010                }
1011        }
1012        else if(BVDC_P_SRC_IS_ANALOG(hSource->eId))
1013        {
1014                /* Support all or limit some for here! */
1015        }
1016        else if(!BVDC_P_SRC_IS_HDDVI(hSource->eId))
1017        {
1018                return BERR_TRACE(BERR_INVALID_PARAMETER);
1019        }
1020
1021        /* set new info */
1022        pNewInfo->pFmtInfo = BFMT_GetVideoFormatInfoPtr(eVideoFmt);
1023        pNewInfo->pVdcFmt  = BVDC_P_GetFormatInfoPtr_isr(pNewInfo->pFmtInfo);
1024
1025        if((hSource->stCurInfo.pFmtInfo->eVideoFmt != eVideoFmt) ||
1026           (hSource->stNewInfo.bErrorLastSetting))
1027        {
1028                /* Dirty bit set */
1029                pNewInfo->stDirty.stBits.bInputFormat = BVDC_P_DIRTY;
1030        }
1031
1032        BDBG_LEAVE(BVDC_Source_SetVideoFormat);
1033        return BERR_SUCCESS;
1034}
1035
1036
1037/***************************************************************************
1038 *
1039 */
1040BERR_Code BVDC_Source_GetVideoFormat
1041        ( const BVDC_Source_Handle         hSource,
1042          BFMT_VideoFmt                   *peVideoFmt )
1043{
1044        BDBG_ENTER(BVDC_Source_GetVideoFormat);
1045        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1046
1047        /* set return value */
1048        if(peVideoFmt)
1049        {
1050                *peVideoFmt = hSource->stCurInfo.pFmtInfo->eVideoFmt;
1051        }
1052
1053        BDBG_LEAVE(BVDC_Source_GetVideoFormat);
1054        return BERR_SUCCESS;
1055}
1056
1057
1058/***************************************************************************
1059 * User call this function to get the interrupt name, so they can create
1060 * callback with BINT_CreateCallback.
1061 *
1062 */
1063BERR_Code BVDC_Source_GetInterruptName
1064        ( BVDC_Source_Handle               hSource,
1065          const BAVC_Polarity              eFieldId,
1066          BINT_Id                         *pInterruptName )
1067{
1068        BDBG_ENTER(BVDC_Source_GetInterruptName);
1069        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1070
1071        if(!BVDC_P_SRC_IS_MPEG(hSource->eId))
1072        {
1073                BDBG_ERR(("Not a MPEG source"));
1074                return BERR_TRACE(BERR_INVALID_PARAMETER);
1075        }
1076
1077        /* set return value */
1078        if(pInterruptName)
1079        {
1080                /* Non-mpeg source should not need the interrupt name. */
1081                *pInterruptName = BRDC_Slot_GetIntId(
1082                        hSource->ahSlot[BVDC_P_NEXT_POLARITY(eFieldId)]);
1083
1084                BDBG_MSG(("What interrupt MVD should response to next "));
1085                BDBG_MSG(("eFieldId==%d?  Ans: %d (or BINT_ID=0x%08x)",
1086                        eFieldId, BVDC_P_NEXT_POLARITY(eFieldId), *pInterruptName));
1087        }
1088
1089        BDBG_LEAVE(BVDC_Source_GetInterruptName);
1090        return BERR_SUCCESS;
1091}
1092
1093/***************************************************************************
1094 *
1095 */
1096BERR_Code BVDC_Source_SetVideoMuteColor
1097        ( BVDC_Source_Handle               hSource,
1098          const uint8_t                    ucRed,
1099          const uint8_t                    ucGreen,
1100          const uint8_t                    ucBlue )
1101{
1102        unsigned int uiColorARGB;
1103        BVDC_P_Source_Info *pNewInfo;
1104
1105        BDBG_ENTER(BVDC_Source_SetVideoMuteColor);
1106        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1107
1108        pNewInfo = &hSource->stNewInfo;
1109
1110        /* set new info */
1111        pNewInfo->ucRed   = ucRed;
1112        pNewInfo->ucGreen = ucGreen;
1113        pNewInfo->ucBlue  = ucBlue;
1114        uiColorARGB = BPXL_MAKE_PIXEL(BPXL_eA8_R8_G8_B8, 0x00, ucRed, ucGreen, ucBlue);
1115        BPXL_ConvertPixel_RGBtoYCbCr(BPXL_eA8_Y8_Cb8_Cr8, BPXL_eA8_R8_G8_B8,
1116                uiColorARGB, (unsigned int*)&pNewInfo->ulMuteColorYCrCb);
1117
1118        if((hSource->stCurInfo.ucRed   != ucRed) ||
1119           (hSource->stCurInfo.ucGreen != ucGreen) ||
1120           (hSource->stCurInfo.ucBlue  != ucBlue) ||
1121           (hSource->stNewInfo.bErrorLastSetting))
1122        {
1123                /* Dirty bit set */
1124                pNewInfo->stDirty.stBits.bUserChanges = BVDC_P_DIRTY;
1125        }
1126
1127        BDBG_LEAVE(BVDC_Source_SetVideoMuteColor);
1128        return BERR_SUCCESS;
1129}
1130
1131/***************************************************************************
1132 *
1133 */
1134BERR_Code BVDC_Source_GetVideoMuteColor
1135        ( const BVDC_Source_Handle          hSource,
1136          uint8_t                          *pucRed,
1137          uint8_t                          *pucGreen,
1138          uint8_t                          *pucBlue )
1139{
1140        BDBG_ENTER(BVDC_Source_GetVideoMuteColor);
1141        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1142
1143        if(pucRed)
1144        {
1145                *pucRed   = hSource->stCurInfo.ucRed;
1146        }
1147
1148        if(pucGreen)
1149        {
1150                *pucGreen = hSource->stCurInfo.ucGreen;
1151        }
1152
1153        if(pucBlue)
1154        {
1155                *pucBlue  = hSource->stCurInfo.ucBlue;
1156        }
1157
1158        BDBG_LEAVE(BVDC_Source_GetVideoMuteColor);
1159        return BERR_SUCCESS;
1160}
1161
1162/***************************************************************************
1163 *
1164 */
1165BERR_Code BVDC_Source_SetMuteMode
1166        ( BVDC_Source_Handle               hSource,
1167          BVDC_MuteMode                    eMuteMode )
1168{
1169        BVDC_P_Source_Info *pNewInfo;
1170
1171        BDBG_ENTER(BVDC_Source_SetMuteMode);
1172        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1173
1174        pNewInfo = &hSource->stNewInfo;
1175
1176        if(eMuteMode > BVDC_MuteMode_eRepeat)
1177        {
1178                return BERR_TRACE(BERR_INVALID_PARAMETER);
1179        }
1180
1181        if(BVDC_P_SRC_IS_MPEG(hSource->eId) &&
1182           (BVDC_MuteMode_eDisable != eMuteMode))
1183        {
1184                BDBG_ERR(("MPEG source %d shall be muted from decoder.", hSource->eId));
1185                return BERR_TRACE(BERR_INVALID_PARAMETER);
1186        }
1187
1188        /* set new value */
1189        pNewInfo->eMuteMode = eMuteMode;
1190
1191        if((hSource->stCurInfo.eMuteMode != eMuteMode) ||
1192           (hSource->stNewInfo.bErrorLastSetting))
1193        {
1194                /* Dirty bit set */
1195                pNewInfo->stDirty.stBits.bUserChanges = BVDC_P_DIRTY;
1196        }
1197
1198        BDBG_LEAVE(BVDC_Source_SetMuteMode);
1199        return BERR_SUCCESS;
1200}
1201
1202/***************************************************************************
1203 *
1204 */
1205BERR_Code BVDC_Source_GetMuteMode
1206        ( const BVDC_Source_Handle          hSource,
1207          BVDC_MuteMode                    *peMuteMode )
1208{
1209        BDBG_ENTER(BVDC_Source_GetMuteMode);
1210        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1211
1212        if(peMuteMode)
1213        {
1214                *peMuteMode = hSource->stCurInfo.eMuteMode;
1215        }
1216
1217        BDBG_LEAVE(BVDC_Source_GetMuteMode);
1218        return BERR_SUCCESS;
1219}
1220
1221/***************************************************************************
1222 *
1223 */
1224BERR_Code BVDC_Source_OverrideAspectRatio
1225        ( BVDC_Source_Handle               hSource,
1226          BFMT_AspectRatio                 eAspectRatio )
1227{
1228        BVDC_P_Source_Info *pNewInfo;
1229
1230        BDBG_ENTER(BVDC_Source_OverrideAspectRatio);
1231        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1232
1233        pNewInfo = &hSource->stNewInfo;
1234
1235        if(eAspectRatio > BFMT_AspectRatio_e15_9)
1236        {
1237                return BERR_TRACE(BERR_INVALID_PARAMETER);
1238        }
1239
1240        /* set new value */
1241        pNewInfo->eAspectRatio  = eAspectRatio;
1242
1243        /* don't auto-update src aspect ratio accoring to videoFmt in
1244         * next ApplyChanges, since user override it */
1245        hSource->bNewUserModeAspRatio = true;
1246
1247        if((hSource->stCurInfo.eAspectRatio != eAspectRatio) ||
1248           (hSource->stNewInfo.bErrorLastSetting))
1249        {
1250                /* Dirty bit set */
1251                pNewInfo->stDirty.stBits.bAspectRatio = BVDC_P_DIRTY;
1252        }
1253
1254        BDBG_LEAVE(BVDC_Source_OverrideAspectRatio);
1255        return BERR_SUCCESS;
1256}
1257
1258/***************************************************************************
1259 *
1260 */
1261BERR_Code BVDC_Source_OverrideAspectRatio_isr
1262        ( BVDC_Source_Handle               hSource,
1263          BFMT_AspectRatio                 eAspectRatio )
1264{
1265        BDBG_ENTER(BVDC_Source_OverrideAspectRatio_isr);
1266        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1267
1268        if(eAspectRatio > BFMT_AspectRatio_e15_9)
1269        {
1270                return BERR_TRACE(BERR_INVALID_PARAMETER);
1271        }
1272
1273        if((hSource->stCurInfo.eAspectRatio != eAspectRatio) ||
1274           ((hSource->stIsrInfo.stDirty.stBits.bAspectRatio) &&
1275                (hSource->stIsrInfo.eAspectRatio != eAspectRatio)))
1276        {
1277                BVDC_P_Source_IsrInfo *pIsrInfo = &hSource->stIsrInfo;
1278                BVDC_P_Source_DirtyBits *pIsrDirty = &pIsrInfo->stDirty;
1279
1280                /* set isr value */
1281                pIsrInfo->eAspectRatio  = eAspectRatio;
1282
1283                /* Dirty bit set */
1284                pIsrDirty->stBits.bAspectRatio = BVDC_P_DIRTY;
1285        }
1286
1287        BDBG_LEAVE(BVDC_Source_OverrideAspectRatio_isr);
1288        return BERR_SUCCESS;
1289}
1290
1291/***************************************************************************
1292 *
1293 */
1294BERR_Code BVDC_Source_GetAspectRatio
1295        ( const BVDC_Source_Handle          hSource,
1296          BFMT_AspectRatio                 *peAspectRatio )
1297{
1298        BDBG_ENTER(BVDC_Source_GetAspectRatio);
1299        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1300
1301        if(peAspectRatio)
1302        {
1303                *peAspectRatio = hSource->stCurInfo.eAspectRatio;
1304        }
1305
1306        BDBG_LEAVE(BVDC_Source_GetAspectRatio);
1307        return BERR_SUCCESS;
1308}
1309
1310
1311/***************************************************************************
1312 *
1313 */
1314BERR_Code BVDC_Source_SetAspectRatioCanvasClip
1315        ( BVDC_Source_Handle               hSource,
1316          uint32_t                         ulLeft,
1317          uint32_t                         ulRight,
1318          uint32_t                         ulTop,
1319          uint32_t                         ulBottom )
1320{
1321        BVDC_P_Source_Info *pNewInfo;
1322
1323        BDBG_ENTER(BVDC_Source_SetAspectRatioCanvasClip);
1324        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1325
1326        pNewInfo = &hSource->stNewInfo;
1327
1328        if(!BVDC_P_SRC_IS_VIDEO(hSource->eId))
1329        {
1330                return BERR_TRACE(BERR_INVALID_PARAMETER);
1331        }
1332
1333
1334        /* set new value */
1335        pNewInfo->stAspRatRectClip.ulLeft   = ulLeft;
1336        pNewInfo->stAspRatRectClip.ulRight  = ulRight;
1337        pNewInfo->stAspRatRectClip.ulTop    = ulTop;
1338        pNewInfo->stAspRatRectClip.ulBottom = ulBottom;
1339        pNewInfo->stAspRatRectClip.lLeftDelta_R = 0;
1340
1341        if((hSource->stCurInfo.stAspRatRectClip.ulLeft   != ulLeft)   ||
1342           (hSource->stCurInfo.stAspRatRectClip.ulRight  != ulRight)  ||
1343           (hSource->stCurInfo.stAspRatRectClip.ulTop    != ulTop)    ||
1344           (hSource->stCurInfo.stAspRatRectClip.ulBottom != ulBottom) ||
1345           (hSource->stNewInfo.bErrorLastSetting))
1346        {
1347                /* Dirty bit set */
1348                pNewInfo->stDirty.stBits.bAspectRatioClip = BVDC_P_DIRTY;
1349        }
1350
1351        BDBG_LEAVE(BVDC_Source_SetAspectRatioCanvasClip);
1352        return BERR_SUCCESS;
1353}
1354
1355/***************************************************************************
1356 *
1357 */
1358BERR_Code BVDC_Source_SetAspectRatioCanvasClip_isr
1359        ( BVDC_Source_Handle               hSource,
1360          uint32_t                         ulLeft,
1361          uint32_t                         ulRight,
1362          uint32_t                         ulTop,
1363          uint32_t                         ulBottom )
1364{
1365        BVDC_P_Source_IsrInfo *pIsrInfo;
1366
1367        BDBG_ENTER(BVDC_Source_SetAspectRatioCanvasClip_isr);
1368        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1369
1370        if(!BVDC_P_SRC_IS_VIDEO(hSource->eId))
1371        {
1372                return BERR_TRACE(BERR_INVALID_PARAMETER);
1373        }
1374
1375        pIsrInfo = &hSource->stIsrInfo;
1376
1377        /* set isr value */
1378        pIsrInfo->stAspRatRectClip.ulLeft   = ulLeft;
1379        pIsrInfo->stAspRatRectClip.ulRight  = ulRight;
1380        pIsrInfo->stAspRatRectClip.ulTop    = ulTop;
1381        pIsrInfo->stAspRatRectClip.ulBottom = ulBottom;
1382        pIsrInfo->stAspRatRectClip.lLeftDelta_R = 0;
1383
1384        if((hSource->stCurInfo.stAspRatRectClip.ulLeft   != ulLeft)   ||
1385           (hSource->stCurInfo.stAspRatRectClip.ulRight  != ulRight)  ||
1386           (hSource->stCurInfo.stAspRatRectClip.ulTop    != ulTop)    ||
1387           (hSource->stCurInfo.stAspRatRectClip.ulBottom != ulBottom) ||
1388           (hSource->stNewInfo.bErrorLastSetting))
1389        {
1390                /* Dirty bit set */
1391                pIsrInfo->stDirty.stBits.bAspectRatioClip = BVDC_P_DIRTY;
1392        }
1393
1394        BDBG_LEAVE(BVDC_Source_SetAspectRatioCanvasClip_isr);
1395        return BERR_SUCCESS;
1396}
1397
1398/***************************************************************************
1399 *
1400 */
1401BERR_Code BVDC_Source_SetAdcConfiguration
1402        ( BVDC_Source_Handle               hSource,
1403          uint32_t                         ulAdcs,
1404          BVDC_AdcInput                    eAdcInput )
1405{
1406        int i;
1407
1408        BDBG_ENTER(BVDC_Source_SetAdcConfiguration);
1409        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1410
1411        /* Update new inputs for each ADC */
1412        for(i = 0; i < BVDC_P_MAX_ADC; i++)
1413        {
1414                if(ulAdcs & (1 << i))
1415                {
1416                        BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
1417                        const BVDC_P_Source_Info *pCurInfo = &hSource->stCurInfo;
1418
1419                        /* set new value */
1420                        pNewInfo->aeAdcInput[i] = eAdcInput;
1421
1422                        /* Dirty bit set */
1423                        if((pNewInfo->aeAdcInput[i] != pCurInfo->aeAdcInput[i]) ||
1424                           (pNewInfo->bErrorLastSetting))
1425                        {
1426                                pNewInfo->stDirty.stBits.bAdcSetting = BVDC_P_DIRTY;
1427                        }
1428                }
1429        }
1430
1431        BDBG_LEAVE(BVDC_Source_SetAdcConfiguration);
1432        return BERR_SUCCESS;
1433}
1434
1435/***************************************************************************
1436 *
1437 */
1438BERR_Code BVDC_Source_GetAdcConfiguration
1439        ( const BVDC_Source_Handle         hSource,
1440          uint32_t                         ulAdc,
1441          BVDC_AdcInput                   *peAdcInput )
1442{
1443        int i;
1444
1445        BDBG_ENTER(BVDC_Source_GetAdcConfiguration);
1446        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1447
1448        /* Don't allow OR-ed of ADC */
1449        if(ulAdc > BVDC_Ibafe_0)
1450        {
1451                return BERR_TRACE(BERR_INVALID_PARAMETER);
1452        }
1453
1454        /* Get index to ADC table */
1455        for(i = 0;
1456                ((i < BVDC_P_MAX_ADC) && (peAdcInput));
1457                i++)
1458        {
1459                if(ulAdc & (1 << i))
1460                {
1461                        *peAdcInput = hSource->stCurInfo.aeAdcInput[i];
1462                        break;
1463                }
1464        }
1465
1466        BDBG_LEAVE(BVDC_Source_GetAdcConfiguration);
1467        return BERR_SUCCESS;
1468}
1469
1470/***************************************************************************
1471 *
1472 */
1473BERR_Code BVDC_Source_Set3DComb
1474        ( BVDC_Source_Handle               hSource,
1475          bool                             b3DComb )
1476{
1477        BVDC_P_Source_Info *pNewInfo;
1478
1479        BDBG_ENTER(BVDC_Source_Set3DComb);
1480        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1481
1482        pNewInfo = &hSource->stNewInfo;
1483
1484        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId))
1485        {
1486                BDBG_ERR(("Source is not VDEC"));
1487                return BERR_TRACE(BERR_INVALID_PARAMETER);
1488        }
1489
1490        /* set new value */
1491        pNewInfo->bEnable3DComb = b3DComb;
1492
1493        if((hSource->stCurInfo.bEnable3DComb != b3DComb) ||
1494           (hSource->stNewInfo.bErrorLastSetting))
1495        {
1496                /* Dirty bit set */
1497                pNewInfo->stDirty.stBits.b3DComb = BVDC_P_DIRTY;
1498        }
1499
1500        BDBG_LEAVE(BVDC_Source_Set3DComb);
1501        return BERR_SUCCESS;
1502}
1503
1504/***************************************************************************
1505 *
1506 */
1507BERR_Code BVDC_Source_Get3DComb
1508        ( BVDC_Source_Handle                hSource,
1509          bool                             *pb3DComb )
1510{
1511        BDBG_ENTER(BVDC_Source_Get3DComb);
1512        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1513
1514        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId))
1515        {
1516                BDBG_ERR(("Source is not VDEC"));
1517                return BERR_TRACE(BERR_INVALID_PARAMETER);
1518        }
1519
1520        if(pb3DComb)
1521        {
1522                *pb3DComb = hSource->stCurInfo.bEnable3DComb;
1523        }
1524
1525        BDBG_LEAVE(BVDC_Source_Get3DComb);
1526
1527        return BERR_SUCCESS;
1528}
1529
1530
1531/***************************************************************************
1532 *
1533 */
1534BERR_Code BVDC_Source_SetVdecConfiguration
1535        ( BVDC_Source_Handle               hSource,
1536          const BVDC_Vdec_Settings        *pVdecSettings )
1537{
1538        BVDC_P_Source_Info *pNewInfo;
1539
1540        BDBG_ENTER(BVDC_Source_SetVdecConfiguration);
1541        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1542
1543        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId))
1544        {
1545                BDBG_ERR(("Source is not VDEC"));
1546                return BERR_TRACE(BERR_INVALID_PARAMETER);
1547        }
1548
1549        pNewInfo  = &hSource->stNewInfo;
1550
1551        /* Take in the customized settings. */
1552        if(pVdecSettings)
1553        {
1554                if(pVdecSettings->pAwc)
1555                {
1556                        pNewInfo->stAwc = *pVdecSettings->pAwc; /* fe */
1557                }
1558                if(pVdecSettings->pCti)
1559                {
1560                        pNewInfo->stCti = *pVdecSettings->pCti; /* cd */
1561                }
1562                if(pVdecSettings->pDcr)
1563                {
1564                        pNewInfo->stDcr = *pVdecSettings->pDcr; /* fe */
1565                }
1566                if(pVdecSettings->pComb)
1567                {
1568                        pNewInfo->stComb = *pVdecSettings->pComb; /* yc */
1569                }
1570                if(pVdecSettings->pAGain)
1571                {
1572                        pNewInfo->stAGain = *pVdecSettings->pAGain; /* fe */
1573                }
1574                if(pVdecSettings->pDGain)
1575                {
1576                        pNewInfo->stDGain = *pVdecSettings->pDGain; /* fe */
1577                }
1578                if(pVdecSettings->pDelay)
1579                {
1580                        pNewInfo->stDelay = *pVdecSettings->pDelay; /* be */
1581                }
1582                if(pVdecSettings->pBackend)
1583                {
1584                        pNewInfo->stBackend = *pVdecSettings->pBackend; /* be */
1585                }
1586
1587                pNewInfo->stVdecSettings = *pVdecSettings;
1588                pNewInfo->stDirty.stBits.bMiscCtrl = BVDC_P_DIRTY;
1589                pNewInfo->bCustomCfg = true;
1590        }
1591        else
1592        {
1593                /* Use/Restore default settings*/
1594                BKNI_Memset((void*)&pNewInfo->stVdecSettings, 0x0, sizeof(BVDC_Vdec_Settings));
1595                BVDC_P_Vdec_InitMisc(&pNewInfo->stVdecSettings, pNewInfo);
1596                pNewInfo->stDirty.stBits.bMiscCtrl = BVDC_P_DIRTY;
1597                pNewInfo->bCustomCfg = false;
1598        }
1599
1600        BDBG_LEAVE(BVDC_Source_SetVdecConfiguration);
1601
1602        return BERR_SUCCESS;
1603}
1604
1605
1606/***************************************************************************
1607 *
1608 */
1609BERR_Code BVDC_Source_GetVdecConfiguration
1610        ( BVDC_Source_Handle               hSource,
1611          BVDC_Vdec_Settings              *pVdecSettings )
1612{
1613        BDBG_ENTER(BVDC_Source_GetVdecConfiguration);
1614        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1615
1616        if(pVdecSettings)
1617        {
1618                const BVDC_Vdec_Settings *pCurSettings = &hSource->stCurInfo.stVdecSettings;
1619
1620                /* Clearout the structure to be filled in. */
1621                BKNI_Memset(pVdecSettings, 0x0, sizeof(BVDC_Vdec_Settings));
1622
1623                /* Always return these */
1624                pVdecSettings->bBypassAcgc       = pCurSettings->bBypassAcgc;
1625                pVdecSettings->bOverSample       = pCurSettings->bOverSample;
1626                pVdecSettings->bBypassCommonMode = pCurSettings->bBypassCommonMode;
1627                pVdecSettings->ulBlackOffset     = pCurSettings->ulBlackOffset;
1628
1629                /* Power user will need to fill it in by themselves. */
1630                /* pVdecSettings->pXYZ = NULL; */
1631        }
1632
1633        BDBG_LEAVE(BVDC_Source_GetVdecConfiguration);
1634
1635        return BERR_SUCCESS;
1636}
1637
1638/***************************************************************************
1639 *
1640 */
1641BERR_Code BVDC_Source_GetVdecDefaultConfiguration
1642        ( BVDC_Source_Handle               hSource,
1643          BVDC_Vdec_Settings              *pVdecSettings )
1644{
1645#if !(BDBG_DEBUG_BUILD)
1646        BSTD_UNUSED(pVdecSettings);
1647#endif
1648
1649        BDBG_ENTER(BVDC_Source_GetVdecDefaultConfiguration);
1650
1651        /* Sanity check input parameters as much as possible */
1652        BDBG_ASSERT(pVdecSettings);
1653
1654        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1655
1656        BVDC_P_Vdec_GetDefaultSettings(hSource->hVdec, pVdecSettings);
1657
1658        BDBG_LEAVE(BVDC_Source_GetVdecDefaultConfiguration);
1659
1660        return BERR_SUCCESS;
1661}
1662
1663
1664/***************************************************************************
1665 *
1666 */
1667BERR_Code BVDC_Source_SetInputPort
1668        ( BVDC_Source_Handle               hSource,
1669          uint32_t                         ulInputPort )
1670{
1671        BVDC_P_Source_Info *pNewInfo;
1672
1673        BDBG_ENTER(BVDC_Source_SetInputPort);
1674        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1675
1676        pNewInfo = &hSource->stNewInfo;
1677
1678        /* set new value */
1679        pNewInfo->ulInputPort = ulInputPort;
1680
1681        if((hSource->stCurInfo.ulInputPort != ulInputPort) ||
1682           (hSource->stNewInfo.bErrorLastSetting))
1683        {
1684                /* Dirty bit set!  Shared the input format/port  dirty bits */
1685                pNewInfo->stDirty.stBits.bInputFormat = BVDC_P_DIRTY;
1686        }
1687
1688        BDBG_LEAVE(BVDC_Source_SetInputPort);
1689        return BERR_SUCCESS;
1690}
1691
1692/***************************************************************************
1693 *
1694 */
1695BERR_Code BVDC_Source_GetInputPort
1696        ( BVDC_Source_Handle               hSource,
1697          uint32_t                        *pulInputPort )
1698{
1699        BDBG_ENTER(BVDC_Source_GetInputPort);
1700        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1701
1702        if(pulInputPort)
1703        {
1704                *pulInputPort = hSource->stCurInfo.ulInputPort;
1705        }
1706
1707        BDBG_LEAVE(BVDC_Source_GetInputPort);
1708
1709        return BERR_SUCCESS;
1710}
1711
1712
1713/***************************************************************************
1714 *
1715 */
1716BERR_Code BVDC_Source_SetAutoFormat
1717        ( BVDC_Source_Handle               hSource,
1718          bool                             bAutoDetect,
1719          BFMT_VideoFmt                    aeFormats[],
1720          uint32_t                         ulNumFormats )
1721{
1722        BVDC_P_Source_Info *pNewInfo;
1723        uint32_t ulIndex;
1724
1725        BDBG_ENTER(BVDC_Source_SetAutoFormat);
1726
1727        BDBG_ASSERT(hSource);
1728        BDBG_ASSERT(ulNumFormats < BFMT_VideoFmt_eMaxCount);
1729        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1730
1731        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId) &&
1732           !BVDC_P_SRC_IS_HDDVI(hSource->eId))
1733        {
1734                BDBG_ERR(("Source is not VDEC"));
1735                return BERR_TRACE(BERR_INVALID_PARAMETER);
1736        }
1737
1738        pNewInfo = &hSource->stNewInfo;
1739
1740        /* set new value */
1741        pNewInfo->bAutoDetect = bAutoDetect;
1742        pNewInfo->ulNumFormats = ulNumFormats;
1743
1744        if((hSource->stCurInfo.bAutoDetect != bAutoDetect)   ||
1745           (hSource->stCurInfo.ulNumFormats != ulNumFormats) ||
1746           (hSource->stNewInfo.bErrorLastSetting))
1747        {
1748                /* Dirty bit set */
1749                pNewInfo->stDirty.stBits.bAutoDetectFmt = BVDC_P_DIRTY;
1750        }
1751
1752        for(ulIndex = 0; ulIndex < ulNumFormats; ulIndex++)
1753        {
1754                pNewInfo->aeFormats[ulIndex] = aeFormats[ulIndex];
1755                if((hSource->stCurInfo.aeFormats[ulIndex] != aeFormats[ulIndex]) ||
1756                   (hSource->stNewInfo.bErrorLastSetting))
1757                {
1758                        pNewInfo->stDirty.stBits.bAutoDetectFmt = BVDC_P_DIRTY;
1759                }
1760        }
1761
1762        BDBG_LEAVE(BVDC_Source_SetAutoFormat);
1763
1764        return BERR_SUCCESS;
1765}
1766
1767/***************************************************************************
1768 *
1769 */
1770BERR_Code BVDC_Source_SetDnrConfiguration
1771        ( BVDC_Source_Handle               hSource,
1772          const BVDC_Dnr_Settings         *pDnrSettings )
1773{
1774#if (!BVDC_P_SUPPORT_DNR)
1775        BSTD_UNUSED(hSource);
1776        BSTD_UNUSED(pDnrSettings);
1777        BDBG_WRN(("DNR is not supported for this chipset"));
1778#else
1779        BDBG_ENTER(BVDC_Source_SetDnrConfiguration);
1780        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1781
1782        if((pDnrSettings->iBnrLevel <= (-1) * BVDC_QP_ADJUST_STEPS) ||
1783           (pDnrSettings->iMnrLevel <= (-1) * BVDC_QP_ADJUST_STEPS) ||
1784           (pDnrSettings->iDcrLevel <= (-1) * BVDC_QP_ADJUST_STEPS))
1785        {
1786                return BERR_TRACE(BERR_INVALID_PARAMETER);
1787        }
1788
1789        /* only support mvd/xvd source; */
1790        if((pDnrSettings->eMnrMode != BVDC_FilterMode_eDisable) ||
1791           (pDnrSettings->eBnrMode != BVDC_FilterMode_eDisable) ||
1792           (pDnrSettings->eDcrMode != BVDC_FilterMode_eDisable))
1793        {
1794                hSource->stNewInfo.bDnr = true;
1795        }
1796        else
1797        {
1798                hSource->stNewInfo.bDnr = false;
1799        }
1800
1801        /* set new value */
1802        hSource->stNewInfo.stDnrSettings = *pDnrSettings;
1803        hSource->stNewInfo.stDirty.stBits.bDnrAdjust = BVDC_P_DIRTY;
1804
1805        BDBG_LEAVE(BVDC_Source_SetDnrConfiguration);
1806#endif
1807
1808        return BERR_SUCCESS;
1809}
1810
1811/***************************************************************************
1812 *
1813 */
1814BERR_Code BVDC_Source_GetDnrConfiguration
1815        ( const BVDC_Source_Handle          hSource,
1816          BVDC_Dnr_Settings                *pDnrSettings )
1817{
1818#if (!BVDC_P_SUPPORT_DNR)
1819        BSTD_UNUSED(hSource);
1820        BSTD_UNUSED(pDnrSettings);
1821        BDBG_WRN(("DNR is not supported for this chipset"));
1822#else
1823        BDBG_ENTER(BVDC_Source_GetDnrConfiguration);
1824        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1825
1826        /* set new value */
1827        if(pDnrSettings)
1828        {
1829                *pDnrSettings = hSource->stCurInfo.stDnrSettings;
1830        }
1831
1832        BDBG_LEAVE(BVDC_Source_GetDnrConfiguration);
1833#endif
1834        return BERR_SUCCESS;
1835}
1836
1837/***************************************************************************
1838 *
1839 */
1840BERR_Code BVDC_Source_SetSplitScreenMode
1841        ( BVDC_Source_Handle                      hSource,
1842          const BVDC_Source_SplitScreenSettings  *pSplitScreen )
1843{
1844        BVDC_P_Source_Info *pNewInfo;
1845
1846        BDBG_ENTER(BVDC_Source_SetSplitScreenMode);
1847        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1848        pNewInfo  = &hSource->stNewInfo;
1849
1850        pNewInfo->stSplitScreenSetting.eDnr = pSplitScreen->eDnr;
1851        if((hSource->stCurInfo.stSplitScreenSetting.eDnr != pSplitScreen->eDnr) ||
1852           (hSource->stNewInfo.bErrorLastSetting))
1853        {
1854                pNewInfo->stDirty.stBits.bDnrAdjust = BVDC_P_DIRTY;
1855        }
1856
1857        BDBG_LEAVE(BVDC_Source_SetSplitScreenMode);
1858        return BERR_SUCCESS;
1859}
1860
1861
1862/***************************************************************************
1863 *
1864 */
1865BERR_Code BVDC_Source_GetSplitScreenMode
1866        ( const BVDC_Source_Handle          hSource,
1867          BVDC_Source_SplitScreenSettings  *pSplitScreen )
1868{
1869        BDBG_ENTER(BVDC_Source_GetSplitScreenMode);
1870        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1871
1872        if(pSplitScreen)
1873        {
1874                *pSplitScreen = hSource->stCurInfo.stSplitScreenSetting;
1875        }
1876
1877        BDBG_LEAVE(BVDC_Source_GetSplitScreenMode);
1878        return BERR_SUCCESS;
1879}
1880
1881/***************************************************************************
1882 *
1883 */
1884BERR_Code BVDC_Source_GetHdDviConfiguration
1885        ( const BVDC_Source_Handle         hSource,
1886          BVDC_HdDvi_Settings             *pHdDviSettings )
1887{
1888        BDBG_ENTER(BVDC_Source_GetHdDviConfiguration);
1889        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1890
1891        if(!BVDC_P_SRC_IS_HDDVI(hSource->eId))
1892        {
1893                BDBG_ERR(("Source is not HD_DVI"));
1894                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
1895        }
1896
1897        if(pHdDviSettings)
1898        {
1899                *pHdDviSettings = hSource->stCurInfo.stHdDviSetting;
1900        }
1901
1902        BDBG_LEAVE(BVDC_Source_GetHdDviConfiguration);
1903        return BERR_SUCCESS;
1904}
1905
1906
1907/***************************************************************************
1908 *
1909 */
1910BERR_Code BVDC_Source_SetHdDviConfiguration
1911        ( BVDC_Source_Handle               hSource,
1912          const BVDC_HdDvi_Settings       *pHdDviSettings )
1913{
1914        BDBG_ENTER(BVDC_Source_SetHdDviConfiguration);
1915        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1916
1917        if(!BVDC_P_SRC_IS_HDDVI(hSource->eId))
1918        {
1919                BDBG_ERR(("Source is not HD_DVI"));
1920                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
1921        }
1922        else
1923        {
1924                BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
1925                BVDC_P_Source_Info *pCurInfo = &hSource->stCurInfo;
1926                BVDC_P_Source_DirtyBits *pNewDirty = &pNewInfo->stDirty;
1927                BVDC_HdDvi_Settings *pCurSetting = &pCurInfo->stHdDviSetting;
1928
1929                /* Enable or disable DE, data mode */
1930                pNewInfo->stHdDviSetting = *pHdDviSettings;
1931                if((pCurSetting->bEnableDe != pHdDviSettings->bEnableDe) ||
1932                   (pCurSetting->eInputDataMode != pHdDviSettings->eInputDataMode) ||
1933                   (pCurSetting->stFmtTolerence.ulWidth  != pHdDviSettings->stFmtTolerence.ulWidth)  ||
1934                   (pCurSetting->stFmtTolerence.ulHeight != pHdDviSettings->stFmtTolerence.ulHeight) ||
1935                   (hSource->stNewInfo.bErrorLastSetting))
1936                {
1937                        pNewDirty->stBits.bMiscCtrl = BVDC_P_DIRTY;
1938                }
1939        }
1940
1941        BDBG_LEAVE(BVDC_Source_SetHdDviConfiguration);
1942        return BERR_SUCCESS;
1943}
1944
1945/***************************************************************************
1946 *
1947 */
1948BERR_Code BVDC_Source_SetSyncConfiguration
1949        ( BVDC_Source_Handle               hSource,
1950          const BVDC_Source_SyncSettings  *pSyncSettings )
1951{
1952        BDBG_ENTER(BVDC_Source_SetSyncConfiguration);
1953        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
1954
1955        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId))
1956        {
1957                BDBG_ERR(("Source is not VDEC"));
1958                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
1959        }
1960        else
1961        {
1962                BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
1963                BVDC_P_Source_Info *pCurInfo = &hSource->stCurInfo;
1964                BVDC_P_Source_DirtyBits *pNewDirty = &pNewInfo->stDirty;
1965
1966                /* set new value */
1967
1968                /* auto/manual clock adjustment */
1969                pNewInfo->stPcInSyncSettings.bManualClock =
1970                        pSyncSettings->bManualClock;
1971                if(pCurInfo->stPcInSyncSettings.bManualClock !=
1972                    pSyncSettings->bManualClock)
1973                {
1974                        pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
1975                }
1976
1977                if(pSyncSettings->bManualClock)
1978                {
1979                        pNewInfo->stPcInSyncSettings.lClockAdj =
1980                                pSyncSettings->lClockAdj;
1981                        if(pCurInfo->stPcInSyncSettings.lClockAdj !=
1982                            pSyncSettings->lClockAdj)
1983                        {
1984                                pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
1985                        }
1986                }
1987                else /* reset to restore the norminal clock */
1988                {
1989                        pNewInfo->stPcInSyncSettings.lClockAdj = 0;
1990                }
1991
1992                /* auto/manual phase adjustment */
1993                pNewInfo->stPcInSyncSettings.bManualPhase =
1994                        pSyncSettings->bManualPhase;
1995                if(pCurInfo->stPcInSyncSettings.bManualPhase !=
1996                    pSyncSettings->bManualPhase)
1997                {
1998                        pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
1999                }
2000
2001                if(pSyncSettings->bManualPhase)
2002                {
2003                        uint32_t ulIndex;
2004                        for(ulIndex = 0; ulIndex < BVDC_COLOR_CHANNELS; ulIndex++)
2005                        {
2006                                pNewInfo->stPcInSyncSettings.aulPhase[ulIndex] =
2007                                        pSyncSettings->aulPhase[ulIndex];
2008                                if(pCurInfo->stPcInSyncSettings.aulPhase[ulIndex] !=
2009                                        pSyncSettings->aulPhase[ulIndex])
2010                                {
2011                                        pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
2012                                }
2013                        }
2014                }
2015
2016#if (BVDC_P_SUPPORT_VDEC_VER >= BVDC_P_VDEC_VER_4)
2017                /* auto/manual position adjustment */
2018                pNewInfo->stPcInSyncSettings.bManualPosition =
2019                        pSyncSettings->bManualPosition;
2020                if(pCurInfo->stPcInSyncSettings.bManualPosition !=
2021                    pSyncSettings->bManualPosition)
2022                {
2023                        pNewDirty->stBits.bManualPos = BVDC_P_DIRTY;
2024                }
2025#endif
2026
2027                /* hysteresis */
2028                pNewInfo->stPcInSyncSettings.bOverrideHysteresis =
2029                        pSyncSettings->bOverrideHysteresis;
2030                if(pCurInfo->stPcInSyncSettings.bOverrideHysteresis!=
2031                    pSyncSettings->bOverrideHysteresis)
2032                {
2033                        pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
2034                }
2035
2036                if(pSyncSettings->bOverrideHysteresis)
2037                {
2038                        pNewInfo->stPcInSyncSettings.ulHysteresis =
2039                                pSyncSettings->ulHysteresis;
2040                        if(pCurInfo->stPcInSyncSettings.ulHysteresis!=
2041                            pSyncSettings->ulHysteresis)
2042                        {
2043                                pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
2044                        }
2045                }
2046                /* manual type */
2047                pNewInfo->stPcInSyncSettings.bOverrideManualType =
2048                        pSyncSettings->bOverrideManualType;
2049                if(pCurInfo->stPcInSyncSettings.bOverrideManualType!=
2050                    pSyncSettings->bOverrideManualType)
2051                {
2052                        pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
2053                }
2054
2055                if(pSyncSettings->bOverrideManualType)
2056                {
2057                        pNewInfo->stPcInSyncSettings.bMultiVsync =
2058                                pSyncSettings->bMultiVsync;
2059                        if(pCurInfo->stPcInSyncSettings.bMultiVsync!=
2060                            pSyncSettings->bMultiVsync)
2061                        {
2062                                pNewDirty->stBits.bManualClk = BVDC_P_DIRTY;
2063                        }
2064                }
2065        }
2066
2067        BDBG_LEAVE(BVDC_Source_SetSyncConfiguration);
2068        return BERR_SUCCESS;
2069}
2070
2071/***************************************************************************
2072 *
2073 */
2074BERR_Code BVDC_Source_GetSyncConfiguration
2075        ( const BVDC_Source_Handle         hSource,
2076          BVDC_Source_SyncSettings        *pSyncSettings )
2077{
2078        BDBG_ENTER(BVDC_Source_GetSyncConfiguration);
2079        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2080
2081        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId))
2082        {
2083                BDBG_ERR(("Source is not VDEC"));
2084                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2085        }
2086
2087        if(pSyncSettings)
2088        {
2089                *pSyncSettings = hSource->stCurInfo.stPcInSyncSettings;
2090        }
2091
2092        BDBG_LEAVE(BVDC_Source_GetSyncConfiguration);
2093        return BERR_SUCCESS;
2094}
2095
2096/***************************************************************************
2097 *
2098 */
2099BERR_Code BVDC_Source_GetSyncStatus
2100        ( const BVDC_Source_Handle         hSource,
2101          BVDC_Source_SyncStatus          *pSyncStatus )
2102{
2103        BDBG_ENTER(BVDC_Source_GetSyncStatus);
2104        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2105
2106        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId) ||
2107           !hSource->stCurInfo.bPcInput)
2108        {
2109                BDBG_ERR(("Source is not PC input"));
2110                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2111        }
2112
2113        if(pSyncStatus)
2114        {
2115                BVDC_P_Vdec_GetPcInSyncStatus(hSource->hVdec, pSyncStatus);
2116        }
2117
2118        BDBG_LEAVE(BVDC_Source_GetSyncStatus);
2119        return BERR_SUCCESS;
2120}
2121
2122/***************************************************************************
2123 *
2124 */
2125BERR_Code BVDC_Source_SetHVStart
2126        ( BVDC_Source_Handle               hSource,
2127          bool                             bOverrideVdc,
2128          uint32_t                         ulHStart,
2129          uint32_t                         ulVStart )
2130{
2131        BDBG_ENTER(BVDC_Source_SetHVStart);
2132        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2133
2134        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId) && !BVDC_P_SRC_IS_HDDVI(hSource->eId))
2135        {
2136                BDBG_ERR(("Source is not VDEC or HD_DVI"));
2137                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2138        }
2139        else
2140        {
2141                BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
2142                BVDC_P_Source_Info *pCurInfo = &hSource->stCurInfo;
2143                BVDC_P_Source_DirtyBits *pNewDirty = &pNewInfo->stDirty;
2144
2145                /* set new value */
2146                /* auto/manual clock adjustment */
2147                pNewInfo->bHVStartOverride = bOverrideVdc;
2148                if(pCurInfo->bHVStartOverride != bOverrideVdc)
2149                {
2150                        pNewDirty->stBits.bManualPos = BVDC_P_DIRTY;
2151                }
2152
2153                if(bOverrideVdc)
2154                {
2155                        pNewInfo->ulHstart = ulHStart;
2156                        pNewInfo->ulVstart = ulVStart;
2157                        if((pCurInfo->ulHstart != ulHStart) ||
2158                           (pCurInfo->ulVstart != ulVStart))
2159                        {
2160                                pNewDirty->stBits.bManualPos = BVDC_P_DIRTY;
2161                        }
2162                }
2163        }
2164
2165        BDBG_LEAVE(BVDC_Source_SetHVStart);
2166        return BERR_SUCCESS;
2167}
2168
2169/***************************************************************************
2170 *
2171 */
2172static BERR_Code BVDC_P_Source_GetHVStart
2173        ( BVDC_Source_Handle               hSource,
2174          bool                            *pbOverrideVdc,
2175          uint32_t                        *pulHStart,
2176          uint32_t                        *pulVStart,
2177          bool                             bGetDefault )
2178{
2179        BDBG_ENTER(BVDC_Source_GetHVStart);
2180        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2181
2182        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId) && !BVDC_P_SRC_IS_HDDVI(hSource->eId))
2183        {
2184                BDBG_ERR(("Source is not VDEC or HD_DVI"));
2185                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2186        }
2187
2188        if(pbOverrideVdc)
2189        {
2190                *pbOverrideVdc = hSource->stCurInfo.bHVStartOverride;
2191        }
2192
2193        if((hSource->stCurInfo.bHVStartOverride) && (!bGetDefault))
2194        {
2195                if(pulHStart)
2196                {
2197                        *pulHStart = hSource->stCurInfo.ulHstart;
2198                }
2199
2200                if(pulVStart)
2201                {
2202                        *pulVStart = hSource->stCurInfo.ulVstart;
2203                }
2204        }
2205        else
2206        {
2207                if(BVDC_P_SRC_IS_ANALOG(hSource->eId))
2208                {
2209                        if(pulHStart)
2210                        {
2211                                /*get ulHstart directly. Is it right?*/
2212                                *pulHStart = hSource->stCurInfo.pFdEntry->ulHStart;
2213                        }
2214
2215                        if(pulVStart)
2216                        {
2217                                /*get ulVstart directly. Is it right?*/
2218                                *pulVStart = hSource->stCurInfo.pFmtInfo->ulTopActive;
2219                        }
2220                }
2221                else if(BVDC_P_SRC_IS_HDDVI(hSource->eId))
2222                {
2223                        if(pulHStart)
2224                        {
2225                                *pulHStart = hSource->hHdDvi->ulHorzDelay;
2226                        }
2227
2228                        if(pulVStart)
2229                        {
2230                                *pulVStart = hSource->hHdDvi->ulVertDelay;
2231                        }
2232                }
2233        }
2234
2235        BDBG_LEAVE(BVDC_Source_GetHVStart);
2236        return BERR_SUCCESS;
2237}
2238
2239/***************************************************************************
2240 *
2241 */
2242BERR_Code BVDC_Source_GetHVStart
2243        ( BVDC_Source_Handle               hSource,
2244          bool                            *pbOverrideVdc,
2245          uint32_t                        *pulHStart,
2246          uint32_t                        *pulVStart )
2247{
2248        return BVDC_P_Source_GetHVStart(hSource, pbOverrideVdc, pulHStart, pulVStart,
2249                false);
2250}
2251
2252
2253/***************************************************************************
2254 *
2255 */
2256BERR_Code BVDC_Source_GetDefaultHVStart
2257        ( BVDC_Source_Handle               hSource,
2258          uint32_t                        *pulHStart,
2259          uint32_t                        *pulVStart )
2260{
2261        return BVDC_P_Source_GetHVStart(hSource, NULL, pulHStart, pulVStart, true);
2262}
2263
2264
2265/***************************************************************************
2266 *
2267 */
2268BERR_Code BVDC_Source_SetOrientation
2269        ( BVDC_Source_Handle               hSource,
2270          bool                             bOverride,
2271          BFMT_Orientation                 eOrientation )
2272{
2273        BDBG_ENTER(BVDC_Source_SetOrientation);
2274        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2275
2276        if(!BVDC_P_SRC_IS_HDDVI(hSource->eId) && !BVDC_P_SRC_IS_MPEG(hSource->eId) &&
2277           !BVDC_P_SRC_IS_GFX(hSource->eId))
2278        {
2279                BDBG_ERR(("Source is not HD_DVI or MPEG or GFX"));
2280                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2281        }
2282        else
2283        {
2284                BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
2285                BVDC_P_Source_Info *pCurInfo = &hSource->stCurInfo;
2286                BVDC_P_Source_DirtyBits *pNewDirty = &pNewInfo->stDirty;
2287
2288                /* set new value */
2289                pNewInfo->bOrientationOverride = bOverride;
2290                if(pCurInfo->bOrientationOverride != bOverride)
2291                {
2292                        pNewDirty->stBits.bOrientation = BVDC_P_DIRTY;
2293                }
2294
2295                if(bOverride)
2296                {
2297                        pNewInfo->eOrientation = eOrientation;
2298                        if(pCurInfo->eOrientation != eOrientation)
2299                        {
2300                                pNewDirty->stBits.bOrientation = BVDC_P_DIRTY;
2301                        }
2302                }
2303        }
2304
2305        BDBG_LEAVE(BVDC_Source_SetOrientation);
2306        return BERR_SUCCESS;
2307
2308}
2309
2310/***************************************************************************
2311 *
2312 */
2313BERR_Code BVDC_Source_GetOrientation
2314        ( BVDC_Source_Handle               hSource,
2315          bool                            *pbOverride,
2316          BFMT_Orientation                *peOrientation )
2317{
2318        BDBG_ENTER(BVDC_Source_GetOrientation);
2319        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2320
2321        if(!BVDC_P_SRC_IS_HDDVI(hSource->eId) && !BVDC_P_SRC_IS_MPEG(hSource->eId) &&
2322           !BVDC_P_SRC_IS_GFX(hSource->eId))
2323        {
2324                BDBG_ERR(("Source is not HD_DVI or MPEG or GFX"));
2325                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2326        }
2327
2328        if(pbOverride)
2329        {
2330                *pbOverride = hSource->stCurInfo.bOrientationOverride;
2331        }
2332
2333        if(peOrientation)
2334        {
2335                *peOrientation = hSource->stCurInfo.eOrientation;
2336        }
2337
2338        BDBG_LEAVE(BVDC_Source_GetOrientation);
2339        return BERR_SUCCESS;
2340
2341}
2342
2343/***************************************************************************
2344 *
2345 */
2346BERR_Code BVDC_Source_SetColorMatrix
2347        ( BVDC_Source_Handle               hSource,
2348          bool                             bOverride,
2349          const int32_t                    pl32_Matrix[BVDC_CSC_COEFF_COUNT],
2350          uint32_t                         ulShift )
2351{
2352        BDBG_ENTER(BVDC_Source_SetColorMatrix);
2353        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2354
2355        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId) &&
2356           !BVDC_P_SRC_IS_HDDVI(hSource->eId))
2357        {
2358                BDBG_ERR(("Source is not VDEC or HDDVI"));
2359                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2360        }
2361        else
2362        {
2363                BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
2364                BVDC_P_Source_DirtyBits *pNewDirty = &pNewInfo->stDirty;
2365
2366                /* set new value */
2367                pNewInfo->bUserCsc = bOverride;
2368                if(bOverride)
2369                {
2370                        uint32_t ulIndex;
2371                        pNewInfo->ulUserShift = ulShift;
2372                        for(ulIndex = 0; ulIndex < BVDC_CSC_COEFF_COUNT; ulIndex++)
2373                        {
2374                                pNewInfo->pl32_Matrix[ulIndex] = pl32_Matrix[ulIndex];
2375                        }
2376                }
2377                pNewDirty->stBits.bColorspace = BVDC_P_DIRTY;
2378        }
2379
2380        BDBG_LEAVE(BVDC_Source_SetColorMatrix);
2381        return BERR_SUCCESS;
2382
2383}
2384
2385/***************************************************************************
2386 *
2387 */
2388BERR_Code BVDC_Source_GetColorMatrix
2389        ( BVDC_Source_Handle               hSource,
2390          bool                            *pbOverride,
2391          int32_t                          pl32_Matrix[BVDC_CSC_COEFF_COUNT],
2392          uint32_t                        *pulShift )
2393{
2394        BDBG_ENTER(BVDC_Source_GetColorMatrix);
2395        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2396
2397        if(pbOverride)
2398        {
2399                *pbOverride = hSource->stCurInfo.bUserCsc;
2400        }
2401
2402        if(hSource->stCurInfo.bUserCsc)
2403        {
2404                uint32_t ulIndex;
2405                for(ulIndex = 0; ulIndex < BVDC_CSC_COEFF_COUNT; ulIndex++)
2406                {
2407                        pl32_Matrix[ulIndex] = hSource->stCurInfo.pl32_Matrix[ulIndex];
2408                }
2409
2410                if(pulShift)
2411                {
2412                        *pulShift = hSource->stCurInfo.ulUserShift;
2413                }
2414        }
2415        else
2416        {
2417                if(BVDC_P_SRC_IS_ANALOG(hSource->eId))
2418                {
2419                        BKNI_EnterCriticalSection();
2420                        BVDC_P_Csc_ToMatrix_isr(pl32_Matrix, &hSource->hVdec->stCsc,
2421                                BVDC_P_FIX_POINT_SHIFT);
2422                        BKNI_LeaveCriticalSection();
2423                }
2424                else if(BVDC_P_SRC_IS_HDDVI(hSource->eId))
2425                {
2426                        BKNI_EnterCriticalSection();
2427                        BVDC_P_Csc_ToMatrix_isr(pl32_Matrix, &hSource->hHdDvi->stCsc,
2428                                BVDC_P_FIX_POINT_SHIFT);
2429                        BKNI_LeaveCriticalSection();
2430                }
2431
2432                if(pulShift)
2433                {
2434                        *pulShift = BVDC_P_FIX_POINT_SHIFT;
2435                }
2436        }
2437
2438        BDBG_LEAVE(BVDC_Source_GetColorMatrix);
2439        return BERR_SUCCESS;
2440}
2441
2442/***************************************************************************
2443 *
2444 */
2445BERR_Code BVDC_Source_SetFrontendColorMatrix
2446        ( BVDC_Source_Handle               hSource,
2447          bool                             bOverride,
2448          const int32_t                    pl32_Matrix[BVDC_CSC_COEFF_COUNT],
2449          uint32_t                         ulShift )
2450{
2451        BDBG_ENTER(BVDC_Source_SetFrontendColorMatrix);
2452        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2453
2454        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId))
2455        {
2456                BDBG_ERR(("Source is not VDEC"));
2457                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2458        }
2459        else
2460        {
2461                BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
2462                BVDC_P_Source_DirtyBits *pNewDirty = &pNewInfo->stDirty;
2463
2464                /* set new value */
2465                pNewInfo->bUserFrontendCsc = bOverride;
2466                if(bOverride)
2467                {
2468                        uint32_t ulIndex;
2469                        pNewInfo->ulUserFrontendShift = ulShift;
2470                        for(ulIndex = 0; ulIndex < BVDC_CSC_COEFF_COUNT; ulIndex++)
2471                        {
2472                                pNewInfo->pl32_FrontendMatrix[ulIndex] = pl32_Matrix[ulIndex];
2473                        }
2474                }
2475                pNewDirty->stBits.bColorspace = BVDC_P_DIRTY;
2476        }
2477
2478        BDBG_LEAVE(BVDC_Source_SetFrontendColorMatrix);
2479        return BERR_SUCCESS;
2480
2481}
2482
2483/***************************************************************************
2484 *
2485 */
2486BERR_Code BVDC_Source_GetFrontendColorMatrix
2487        ( BVDC_Source_Handle               hSource,
2488          bool                            *pbOverride,
2489          int32_t                          pl32_Matrix[BVDC_CSC_COEFF_COUNT],
2490          uint32_t                        *pulShift )
2491{
2492        BDBG_ENTER(BVDC_Source_GetFrontendColorMatrix);
2493        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2494
2495        if(pbOverride)
2496        {
2497                *pbOverride = hSource->stCurInfo.bUserFrontendCsc;
2498        }
2499
2500        if(hSource->stCurInfo.bUserFrontendCsc)
2501        {
2502                uint32_t ulIndex;
2503                for(ulIndex = 0; ulIndex < BVDC_CSC_COEFF_COUNT; ulIndex++)
2504                {
2505                        pl32_Matrix[ulIndex] = hSource->stCurInfo.pl32_FrontendMatrix[ulIndex];
2506                }
2507
2508                if(pulShift)
2509                {
2510                        *pulShift = hSource->stCurInfo.ulUserFrontendShift;
2511                }
2512        }
2513        else
2514        {
2515                if(BVDC_P_SRC_IS_ANALOG(hSource->eId))
2516                {
2517                        BKNI_EnterCriticalSection();
2518                        BVDC_P_Csc_ToMatrix_isr(pl32_Matrix, &hSource->hVdec->stFrontendCsc,
2519                                BVDC_P_FIX_POINT_SHIFT);
2520                        BKNI_LeaveCriticalSection();
2521                }
2522                /* else * return unmodified structure */
2523
2524                if(pulShift)
2525                {
2526                        *pulShift = BVDC_P_FIX_POINT_SHIFT;
2527                }
2528        }
2529
2530        BDBG_LEAVE(BVDC_Source_GetFrontendColorMatrix);
2531        return BERR_SUCCESS;
2532}
2533
2534/***************************************************************************
2535 *
2536 */
2537BERR_Code BVDC_Source_GetInputStatus
2538        ( const BVDC_Source_Handle         hSource,
2539          BVDC_Source_InputStatus         *pInputStatus )
2540{
2541        BDBG_ENTER(BVDC_Source_GetInputStatus);
2542        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2543
2544        if(!BVDC_P_SRC_IS_HDDVI(hSource->eId) &&
2545           !BVDC_P_SRC_IS_ANALOG(hSource->eId))
2546        {
2547                BDBG_ERR(("Source is not PC, Component or HD_DVI input"));
2548                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2549        }
2550
2551        if(pInputStatus)
2552        {
2553                /* To make sure thing get initialize */
2554                BKNI_Memset(pInputStatus, 0, sizeof(*pInputStatus));
2555
2556                if(BVDC_P_SRC_IS_ANALOG(hSource->eId))
2557                {
2558                        BVDC_P_Vdec_GetInputStatus(hSource->hVdec, pInputStatus);
2559                }
2560                else if(BVDC_P_SRC_IS_HDDVI(hSource->eId))
2561                {
2562                        BVDC_P_HdDvi_GetInputStatus(hSource->hHdDvi, pInputStatus);
2563                }
2564        }
2565
2566        BDBG_LEAVE(BVDC_Source_GetInputStatus);
2567        return BERR_SUCCESS;
2568}
2569
2570/***************************************************************************
2571 *
2572 */
2573BERR_Code BVDC_Source_SetPsfMode
2574        ( BVDC_Source_Handle               hSource,
2575          bool                             bEnable )
2576{
2577        BDBG_ENTER(BVDC_Source_SetPsfMode);
2578        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2579
2580        if(!BVDC_P_SRC_IS_MPEG(hSource->eId))
2581        {
2582                BDBG_ERR(("Source is not MPEG input"));
2583                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2584        }
2585
2586        hSource->stNewInfo.bPsfEnable = bEnable;
2587        if(hSource->stCurInfo.bPsfEnable != bEnable)
2588        {
2589                /* Dirty bit set */
2590                hSource->stNewInfo.stDirty.stBits.bPsfMode = BVDC_P_DIRTY;
2591        }
2592
2593        BDBG_LEAVE(BVDC_Source_SetPsfMode);
2594        return BERR_SUCCESS;
2595}
2596
2597
2598/***************************************************************************
2599 *
2600 */
2601BERR_Code BVDC_Source_GetPsfMode
2602        ( BVDC_Source_Handle               hSource,
2603          bool                            *pbEnable )
2604{
2605        BDBG_ENTER(BVDC_Source_GetPsfMode);
2606        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2607
2608        if(!BVDC_P_SRC_IS_MPEG(hSource->eId))
2609        {
2610                BDBG_ERR(("Source is not MPEG input"));
2611                return BERR_TRACE(BVDC_ERR_BAD_SRC_TYPE);
2612        }
2613
2614        if(pbEnable)
2615        {
2616                *pbEnable = hSource->stCurInfo.bPsfEnable;
2617        }
2618
2619        BDBG_LEAVE(BVDC_Source_GetPsfMode);
2620        return BERR_SUCCESS;
2621}
2622
2623
2624/***************************************************************************
2625 *
2626 */
2627BERR_Code BVDC_Source_SetReMapFormats
2628        ( BVDC_Source_Handle               hSource,
2629          bool                             bReMap,
2630          const BVDC_VideoFmtPair          aReMapFormats[],
2631          uint32_t                         ulReMapFormats )
2632{
2633        uint32_t i;
2634        BVDC_P_Source_Info *pNewInfo;
2635
2636        BDBG_ENTER(BVDC_Source_SetReMapFormats);
2637        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2638
2639        if(!BVDC_P_SRC_IS_ANALOG(hSource->eId) &&
2640           !BVDC_P_SRC_IS_HDDVI(hSource->eId))
2641        {
2642                BDBG_ERR(("Source is not VDEC/HD_DVI"));
2643                return BERR_TRACE(BERR_INVALID_PARAMETER);
2644        }
2645
2646        if(ulReMapFormats >= BFMT_VideoFmt_eMaxCount)
2647        {
2648                BDBG_ERR(("Out of bound ulReMapFormats = %d", ulReMapFormats));
2649                return BERR_TRACE(BERR_INVALID_PARAMETER);
2650        }
2651
2652        pNewInfo = &hSource->stNewInfo;
2653
2654        /* set new value */
2655        pNewInfo->bReMapFormats = bReMap;
2656        pNewInfo->ulReMapFormats = ulReMapFormats;
2657
2658        if((bReMap) && (ulReMapFormats))
2659        {
2660                for(i = 0; i < ulReMapFormats; i++)
2661                {
2662                        pNewInfo->aReMapFormats[i] = aReMapFormats[i];
2663                }
2664        }
2665
2666        /* Dirty bit set */
2667        pNewInfo->stDirty.stBits.bAutoDetectFmt = BVDC_P_DIRTY;
2668
2669        BDBG_LEAVE(BVDC_Source_SetReMapFormats);
2670        return BERR_SUCCESS;
2671}
2672
2673
2674/***************************************************************************
2675 *
2676 */
2677BERR_Code BVDC_Source_InstallPictureCallback
2678        ( BVDC_Source_Handle               hSource,
2679          BVDC_Source_PictureCallback_isr  pfSrcCallback,
2680          void                            *pvParm1,
2681          int                              iParm2 )
2682{
2683        BVDC_P_Source_Info *pNewInfo;
2684
2685        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2686
2687        pNewInfo = &hSource->stNewInfo;
2688
2689        if((!BVDC_P_SRC_IS_HDDVI(hSource->eId)) &&
2690           (!BVDC_P_SRC_IS_GFX(hSource->eId)) &&
2691           (!BVDC_P_SRC_IS_VFD(hSource->eId)))
2692        {
2693                BDBG_ERR(("Source is not HD_DVI, VFD, or GFX"));
2694                return BERR_TRACE(BERR_INVALID_PARAMETER);
2695        }
2696
2697        /* set new info and dirty bits. */
2698        pNewInfo->pfPicCallbackFunc = pfSrcCallback;
2699        pNewInfo->pvParm1 = pvParm1;
2700        pNewInfo->iParm2 = iParm2;
2701
2702        if((hSource->stCurInfo.pfPicCallbackFunc != pfSrcCallback) ||
2703           (hSource->stCurInfo.pvParm1 != pvParm1) ||
2704           (hSource->stCurInfo.iParm2 != iParm2)   ||
2705           (hSource->stNewInfo.bErrorLastSetting))
2706        {
2707                /* Dirty bit set */
2708                pNewInfo->stDirty.stBits.bPicCallback = BVDC_P_DIRTY;
2709        }
2710
2711        return BERR_SUCCESS;
2712}
2713
2714
2715/***************************************************************************
2716 *
2717 */
2718BERR_Code BVDC_Source_InstallCallback
2719        ( BVDC_Source_Handle               hSource,
2720          const BVDC_CallbackFunc_isr      pfCallback,
2721          void                            *pvParm1,
2722          int                              iParm2 )
2723{
2724        BVDC_P_Source_Info *pNewInfo;
2725
2726        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2727
2728        pNewInfo = &hSource->stNewInfo;
2729
2730        /* set new info and dirty bits. */
2731        pNewInfo->pfGenericCallback = pfCallback;
2732        pNewInfo->pvGenericParm1 = pvParm1;
2733        pNewInfo->iGenericParm2 = iParm2;
2734
2735        if((hSource->stCurInfo.pfGenericCallback != pfCallback) ||
2736           (hSource->stCurInfo.pvGenericParm1 != pvParm1) ||
2737           (hSource->stCurInfo.iGenericParm2 != iParm2)   ||
2738           (hSource->stNewInfo.bErrorLastSetting))
2739        {
2740                /* Dirty bit set */
2741                pNewInfo->stDirty.stBits.bGenCallback = BVDC_P_DIRTY;
2742        }
2743
2744        return BERR_SUCCESS;
2745}
2746
2747
2748/***************************************************************************
2749 *
2750 */
2751BERR_Code BVDC_Source_SetResumeMode
2752        ( BVDC_Source_Handle               hSource,
2753          BVDC_ResumeMode                  eResumeMode )
2754{
2755        BVDC_P_Source_Info *pNewInfo;
2756
2757        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2758
2759        pNewInfo = &hSource->stNewInfo;
2760
2761        /* set new info and dirty bits. */
2762        pNewInfo->eResumeMode = eResumeMode;
2763
2764        if((hSource->stCurInfo.eResumeMode != eResumeMode) ||
2765           (hSource->stNewInfo.bErrorLastSetting))
2766        {
2767                /* Dirty bit set */
2768                pNewInfo->stDirty.stBits.bUserChanges = BVDC_P_DIRTY;
2769        }
2770
2771        return BERR_SUCCESS;
2772}
2773
2774
2775/***************************************************************************
2776 *
2777 */
2778BERR_Code BVDC_Source_GetResumeMode
2779        ( BVDC_Source_Handle               hSource,
2780          BVDC_ResumeMode                 *peResumeMode )
2781{
2782        BDBG_ENTER(BVDC_Source_GetResumeMode);
2783        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2784
2785        if(peResumeMode)
2786        {
2787                *peResumeMode = hSource->stCurInfo.eResumeMode;
2788        }
2789
2790        BDBG_LEAVE(BVDC_Source_GetResumeMode);
2791        return BERR_SUCCESS;
2792}
2793
2794
2795/***************************************************************************
2796 *
2797 */
2798BERR_Code BVDC_Source_Resume
2799        ( BVDC_Source_Handle               hSource )
2800{
2801        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2802
2803        /* set new info and dirty bits. */
2804        hSource->stNewInfo.stDirty.stBits.bResume = BVDC_P_DIRTY;
2805
2806        return BERR_SUCCESS;
2807}
2808
2809
2810/***************************************************************************
2811 *
2812 */
2813BERR_Code BVDC_Source_ForcePending
2814        ( BVDC_Source_Handle               hSource )
2815{
2816        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
2817
2818        /* set new info and dirty bits. */
2819        hSource->stNewInfo.bForceSrcPending = true;
2820
2821        return BERR_SUCCESS;
2822}
2823
2824/***************************************************************************
2825 *
2826 */
2827BERR_Code BVDC_Source_GetCapabilities
2828        ( const BVDC_Source_Handle         hSource,
2829          BVDC_Source_Capabilities        *pCapabilities )
2830{
2831        BSTD_UNUSED(hSource);
2832
2833        if(pCapabilities)
2834        {
2835                /* To make sure thing get initialize */
2836                BKNI_Memset(pCapabilities, 0, sizeof(*pCapabilities));
2837               
2838                pCapabilities->pfIsPxlfmtSupported = BVDC_P_IsPxlfmtSupported;
2839        }
2840
2841        return BERR_SUCCESS;
2842}
2843
2844
2845#if (BDBG_DEBUG_BUILD)
2846/***************************************************************************
2847 *
2848 */
2849static void BVDC_P_Source_PrintPicture
2850        ( const BVDC_Source_Handle         hSource,
2851          const BAVC_MVD_Field            *pCurPic,
2852          const BAVC_MVD_Field            *pNewPic )
2853{
2854        uint32_t ulMsgCount;
2855        uint32_t ulPrintOnDelta;
2856        uint32_t ulDebugReg = BVDC_P_MPEG_DEBUG_SCRATCH(hSource->eId);
2857
2858        ulMsgCount = BREG_Read32_isr(hSource->hVdc->hRegister, ulDebugReg);
2859
2860        /* bit 1: print on mpeg-pic-delta;
2861         * other 31-bit: message count; */
2862        ulPrintOnDelta = ulMsgCount & 1;
2863
2864        /* Check if different from previous field. */
2865        if(ulPrintOnDelta)
2866        {
2867                /* If interlaced make sure the polarity are not repeat. */
2868                if((false == pNewPic->bMute) &&
2869                   (BAVC_Polarity_eFrame != pNewPic->eSourcePolarity) &&
2870                   (pNewPic->eSourcePolarity == pCurPic->eSourcePolarity))
2871                {
2872                        BDBG_ERR(("*** XDM sends repeated buffer (%s)!",
2873                                (BAVC_Polarity_eTopField == pNewPic->eSourcePolarity) ? "T" :
2874                                (BAVC_Polarity_eBotField == pNewPic->eSourcePolarity) ? "B" : "F"));
2875                }
2876                ulPrintOnDelta = (uint32_t)hSource->bPictureChanged ||
2877                        BVDC_P_FIELD_DIFF(pNewPic, pCurPic, bStreamProgressive) ||
2878                        BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eMpegType) ||
2879                        BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eYCbCrType) ||
2880                        BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eAspectRatio) ||
2881                        BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eFrameRateCode) ||
2882                        BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eMatrixCoefficients) ||
2883                        BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eChrominanceInterpolationMode);
2884        }
2885
2886        if((ulMsgCount >= 2) || (ulPrintOnDelta))
2887        {
2888                BAVC_MVD_Field *pPic = (BAVC_MVD_Field *)pNewPic;
2889                uint32_t ulPicIdx = 0;
2890                do {
2891                        BDBG_ERR(("---------------------------------- pic %d", ulPicIdx++));
2892                        BDBG_ERR(("src_id                        : mfd%d", hSource->eId));
2893                        BDBG_ERR(("pPic->bMute                   : %d", pPic->bMute));
2894                        BDBG_ERR(("pPic->ulAdjQp                 : %d", pPic->ulAdjQp));
2895                        BDBG_ERR(("pPic->bCaptureCrc             : %d", pPic->bCaptureCrc));
2896                        BDBG_ERR(("pPic->ulOrigPTS               : %d", pPic->ulOrigPTS));
2897                        BDBG_ERR(("pPic->ulIdrPicID              : %d", pPic->ulIdrPicID));
2898                        BDBG_ERR(("pPic->int32_PicOrderCnt       : %d", pPic->int32_PicOrderCnt));
2899                        BDBG_ERR(("pPic->eSourcePolarity         : %d", pPic->eSourcePolarity));
2900                        BDBG_ERR(("pPic->eInterruptPolarity      : %d", pPic->eInterruptPolarity));
2901                        BDBG_ERR(("pPic->eChrominanceIntMode     : %d", pPic->eChrominanceInterpolationMode));
2902                        BDBG_ERR(("pPic->eMpegType               : %d", pPic->eMpegType));
2903                        BDBG_ERR(("pPic->eYCbCrType              : %d", pPic->eYCbCrType));
2904                        BDBG_ERR(("pPic->eAspectRatio            : %d", pPic->eAspectRatio));
2905                        BDBG_ERR(("pPic->uiSampleAspectRatioX    : %d", pPic->uiSampleAspectRatioX));
2906                        BDBG_ERR(("pPic->uiSampleAspectRatioY    : %d", pPic->uiSampleAspectRatioY));
2907                        BDBG_ERR(("pPic->eFrameRateCode          : %d", pPic->eFrameRateCode));
2908                        BDBG_ERR(("pPic->eMatrixCoefficients     : %d", pPic->eMatrixCoefficients));
2909                        BDBG_ERR(("pPic->bStreamProgressive      : %d", pPic->bStreamProgressive));
2910                        BDBG_ERR(("pPic->bFrameProgressive       : %d", pPic->bFrameProgressive));
2911                        BDBG_ERR(("pPic->hHeap                   : 0x%08x", pPic->hHeap));
2912                        BDBG_ERR(("pPic->pChrominanceBufAddr     : 0x%08x", pPic->pChrominanceFrameBufferAddress));
2913                        BDBG_ERR(("pPic->pLuminanceBufAddr       : 0x%08x", pPic->pLuminanceFrameBufferAddress));
2914                        BDBG_ERR(("pPic->ulRowStride             : 0x%08x", pPic->ulRowStride));
2915                        BDBG_ERR(("pPic->ulLuminanceNMBY         : %d", pPic->ulLuminanceNMBY));
2916                        BDBG_ERR(("pPic->ulChrominanceNMBY       : %d", pPic->ulChrominanceNMBY));
2917                        BDBG_ERR(("pPic->ulLumaRangeRemapping    : 0x%x", pPic->ulLumaRangeRemapping));
2918                        BDBG_ERR(("pPic->ulChromaRangeRemapping  : 0x%x", pPic->ulChromaRangeRemapping));
2919                        BDBG_ERR(("pPic->ulDisplayHorizontalSize : %d", pPic->ulDisplayHorizontalSize));
2920                        BDBG_ERR(("pPic->ulDisplayVerticalSize   : %d", pPic->ulDisplayVerticalSize));
2921                        BDBG_ERR(("pPic->ulSourceHorizontalSize  : %d", pPic->ulSourceHorizontalSize));
2922                        BDBG_ERR(("pPic->ulSourceVerticalSize    : %d", pPic->ulSourceVerticalSize));
2923                        BDBG_ERR(("pPic->i32_HorizontalPanScan   : %d", pPic->i32_HorizontalPanScan));
2924                        BDBG_ERR(("pPic->i32_VerticalPanScan     : %d", pPic->i32_VerticalPanScan));
2925                        BDBG_ERR(("pPic->ulSourceClipLeft        : %d", pPic->ulSourceClipLeft));
2926                        BDBG_ERR(("pPic->ulSourceClipTop         : %d", pPic->ulSourceClipTop));
2927                        BDBG_ERR(("pPic->hSurface                : 0x%08x", pPic->hSurface));
2928                        BDBG_ERR(("pPic->bPictureRepeatFlag      : %d", pPic->bPictureRepeatFlag));
2929                        BDBG_ERR(("pPic->hFgtHeap                : 0x%08x", pPic->hFgtHeap));
2930                        BDBG_ERR(("pPic->pFgtSeiBufferAddress    : 0x%08x", pPic->pFgtSeiBufferAddress));
2931                        BDBG_ERR(("pPic->ulChannelId             : %d", pPic->ulChannelId));
2932                        BDBG_ERR(("pPic->eStripeWidth            : %d", pPic->eStripeWidth));
2933                        BDBG_ERR(("pPic->bIgnoreCadenceMatch     : %d", pPic->bIgnoreCadenceMatch));
2934                        BDBG_ERR(("pPic->bValidAfd               : %d", pPic->bValidAfd));
2935                        BDBG_ERR(("pPic->ulAfd                   : %d", pPic->ulAfd));
2936                        BDBG_ERR(("pPic->eBarDataType            : %d", pPic->eBarDataType));
2937                        BDBG_ERR(("pPic->ulTopLeftBarValue       : %d", pPic->ulTopLeftBarValue));
2938                        BDBG_ERR(("pPic->ulBotRightBarValue      : %d", pPic->ulBotRightBarValue));
2939                        BDBG_ERR(("pPic->eOrientation            : %d", pPic->eOrientation));
2940                        BDBG_ERR(("pPic->pNext                   : %p", pPic->pNext));
2941                        BDBG_ERR(("pPic->pEnhanced               : %p", pPic->pEnhanced));
2942                        if(pPic->pEnhanced)
2943                        {
2944                                BAVC_MVD_Field *pEnhanced = (BAVC_MVD_Field *)pPic->pEnhanced;
2945
2946                                BDBG_ERR(("pPic->pEnhanced->eOrientation       : %p",     pEnhanced->eOrientation));
2947                                BDBG_ERR(("pPic->pEnhanced->pChrominanceBufAddr: 0x%08x", pEnhanced->pChrominanceFrameBufferAddress));
2948                                BDBG_ERR(("pPic->pEnhanced->pLuminanceBufAddr  : 0x%08x", pEnhanced->pLuminanceFrameBufferAddress));
2949                        }
2950                        pPic = pPic->pNext;
2951                }while (pPic);
2952
2953                /* keep on printing until we get to zero, and update field. */
2954                if(ulMsgCount >= 2)
2955                {
2956                        BREG_Write32_isr(hSource->hVdc->hRegister, ulDebugReg, ulMsgCount - 2);
2957                }
2958        }
2959        return;
2960}
2961#endif
2962
2963
2964/**************************************************************************
2965 *
2966 */
2967void BVDC_P_Source_ValidateMpegData_isr
2968        ( BVDC_Source_Handle         hSource,
2969          BAVC_MVD_Field            *pNewPic,
2970          const BAVC_MVD_Field      *pCurPic)
2971{
2972
2973                /* SW7425-686 solve XVD and BVN refresh rate mismatch problem */
2974                if(hSource->hSyncLockCompositor)
2975                {
2976                        const BFMT_VideoInfo *pFmtInfo;
2977                        uint32_t ulSrcVerq = 0;
2978
2979                        pFmtInfo = hSource->hSyncLockCompositor->hDisplay->stCurInfo.pFmtInfo;
2980                        hSource->bFreshRateMismatch = false;
2981
2982                        if(pNewPic->bMute == false)
2983                        {
2984                                switch(pNewPic->eInterruptRefreshRate)
2985                                {
2986                                        case(BFMT_Vert_e23_976Hz):
2987                                                ulSrcVerq = 2397; break;
2988                                        case(BFMT_Vert_e24Hz):
2989                                                ulSrcVerq = 2400; break;
2990                                        case(BFMT_Vert_e25Hz):
2991                                                ulSrcVerq = 2500; break;
2992                                        case(BFMT_Vert_e29_97Hz):
2993                                                ulSrcVerq = 2997; break;
2994                                        case(BFMT_Vert_e30Hz):
2995                                                ulSrcVerq = 3000; break;
2996                                        case(BFMT_Vert_e48Hz):
2997                                                ulSrcVerq =4800; break;
2998                                        case(BFMT_Vert_e50Hz):
2999                                                ulSrcVerq = 5000; break;
3000                                        case(BFMT_Vert_e59_94Hz):
3001                                                ulSrcVerq = 5994; break;
3002                                        case(BFMT_Vert_e60Hz):
3003                                                ulSrcVerq = 6000; break;
3004                                        case(BFMT_Vert_eInvalid):
3005                                        case(BFMT_Vert_eLast):
3006                                        default:
3007                                        /* @@@ SW7425-832: set SrcVerq to Display fresh rate
3008                                        when BFMT_Vert_eInvalid or BFMT_Vert_eLast.
3009                                        Need to check with XVD why it is invalid number */
3010                                        ulSrcVerq = pFmtInfo->ulVertFreq; break;
3011                                }
3012
3013                                if(!BVDC_P_EQ_DELTA (ulSrcVerq, pFmtInfo->ulVertFreq, 10)) {
3014                                        hSource->bFreshRateMismatch  = true;
3015                                        BDBG_WRN(("XVD -> BVN refresh rate mismatch! XVD %4d x %4d @ %4d BVN %4d x %4d @ %4d",
3016                                        pNewPic->ulSourceHorizontalSize, pNewPic->ulSourceVerticalSize, pNewPic->eInterruptRefreshRate,
3017                                        pFmtInfo->ulDigitalWidth, pFmtInfo->ulDigitalHeight, pFmtInfo->ulVertFreq));
3018                                }
3019                        }
3020                }
3021
3022        /* for gfx surface displayed as mpeg buffer */
3023        if(pNewPic->hSurface && (pNewPic->ePxlFmt == BPXL_INVALID))
3024        {
3025                BERR_Code eResult = BERR_SUCCESS;
3026
3027                /* init *pNewPic for late */
3028                pNewPic->bStreamProgressive = true;
3029                pNewPic->bFrameProgressive  = true;
3030                pNewPic->eMpegType  = BAVC_MpegType_eMpeg2;
3031                pNewPic->eYCbCrType = BAVC_YCbCrType_e4_2_2;
3032                pNewPic->eChrominanceInterpolationMode = BAVC_InterpolationMode_eFrame;
3033               
3034                eResult |= BSUR_Surface_GetAddress(pNewPic->hSurface,
3035                        &pNewPic->pLuminanceFrameBufferAddress, &pNewPic->ulRowStride);
3036                eResult |= BSUR_Surface_GetDimensions(pNewPic->hSurface,
3037                        &pNewPic->ulSourceHorizontalSize, &pNewPic->ulSourceVerticalSize);
3038                eResult |= BSUR_Surface_GetFormat(pNewPic->hSurface, &pNewPic->ePxlFmt);
3039
3040                /*  Null means to use the same main heap of VDC; */
3041                if(!pNewPic->hHeap)
3042                {
3043                        pNewPic->hHeap = hSource->hVdc->hMemory;
3044                }
3045               
3046                /* top fld sur only has even lines (including line 0) of the frame,
3047                 * and bot sur only has odd lines */
3048                if(BAVC_Polarity_eFrame != pNewPic->eSourcePolarity)
3049                {
3050                        pNewPic->ulSourceVerticalSize *= 2;
3051                }
3052
3053                /* H & V size alignment */
3054                /* Jira SW7405-4239: XMD might send odd width for special aspect ratio purpose
3055                  pNewPic->ulSourceHorizontalSize = pNewPic->ulSourceHorizontalSize & ~1; */
3056                pNewPic->ulSourceVerticalSize   = pNewPic->ulSourceVerticalSize & ~1;
3057
3058                /* Check if fields that are to be written to registers fit
3059                 * within their field sizes. */
3060                if(!BVDC_P_SRC_VALIDATE_FIELD(MFD_0_STRIDE, PACKED_LINE_STRIDE, pNewPic->ulRowStride))
3061                {
3062                        BDBG_ERR(("ulRowStride is invalid"));
3063                        pNewPic->ulRowStride = BVDC_P_SRC_FIELD_DATA_MASK(MFD_0_STRIDE,
3064                                PACKED_LINE_STRIDE, pNewPic->ulRowStride);
3065                }
3066        }
3067
3068        /* Not gfx surface displayed as mpeg buffer case:
3069         * if null address or size => force mute */
3070        /* if requested to capture CRC, don't adjust original source size */
3071        if((!pNewPic->bCaptureCrc) && (pNewPic->ePxlFmt == BPXL_INVALID) &&
3072           ((pNewPic->ulSourceHorizontalSize < BVDC_P_SRC_INPUT_H_MIN) ||
3073            (pNewPic->ulSourceVerticalSize   < BVDC_P_SRC_INPUT_V_MIN) ||
3074            (!pNewPic->pLuminanceFrameBufferAddress) ||
3075            (!pNewPic->pChrominanceFrameBufferAddress)))
3076        {
3077                pNewPic->ulSourceHorizontalSize  = BVDC_P_SRC_INPUT_H_MIN;
3078                pNewPic->ulSourceVerticalSize    = BVDC_P_SRC_INPUT_V_MIN;
3079                pNewPic->ulDisplayHorizontalSize = BVDC_P_SRC_INPUT_H_MIN;
3080                pNewPic->ulDisplayVerticalSize   = BVDC_P_SRC_INPUT_V_MIN;
3081                pNewPic->bMute = true;
3082        }
3083
3084        /* Avoid invalid size that can lock up BVN when muted */
3085        if(!pNewPic->bCaptureCrc || pNewPic->bMute)
3086        {
3087                /* (1) Source/display size are invalid.  Corrected them here.  Non-zero. */
3088                if((pNewPic->ulSourceHorizontalSize  < BVDC_P_SRC_INPUT_H_MIN) ||
3089                   (pNewPic->ulSourceVerticalSize    < BVDC_P_SRC_INPUT_V_MIN))
3090                {
3091                        pNewPic->ulSourceHorizontalSize  = BVDC_P_SRC_INPUT_H_MIN;
3092                        pNewPic->ulSourceVerticalSize    = BVDC_P_SRC_INPUT_V_MIN;
3093                }
3094
3095                /* (2) If we receiving 1088i stream we will assume it contains the
3096                 * non-active video in the last 8 lines.  We'll drop them.  PR10698.  Or
3097                 * any value that might break the VDC (restricting to HW limit, not
3098                 * necessary rts limit). */
3099                if((1088 == pNewPic->ulSourceVerticalSize)
3100#ifdef BCHP_MFD_0_DISP_VSIZE_VALUE_MASK
3101                   || (!BVDC_P_SRC_VALIDATE_FIELD(MFD_0_DISP_VSIZE, VALUE, pNewPic->ulSourceVerticalSize))
3102#endif
3103#ifdef BCHP_MFD_0_DISP_HSIZE_VALUE_MASK
3104                   || (!BVDC_P_SRC_VALIDATE_FIELD(MFD_0_DISP_HSIZE, VALUE, pNewPic->ulSourceHorizontalSize))
3105#endif
3106#ifdef BCHP_MFD_0_PICTURE0_DISP_VERT_WINDOW_START_MASK
3107                   || (!BVDC_P_SRC_VALIDATE_FIELD(MFD_0_PICTURE0_DISP_VERT_WINDOW, START, pNewPic->ulSourceVerticalSize))
3108#endif
3109                  )
3110                {
3111                        pNewPic->ulSourceVerticalSize    =
3112                                BVDC_P_MIN(pNewPic->ulSourceVerticalSize,    BFMT_1080I_HEIGHT);
3113                        pNewPic->ulSourceHorizontalSize  =
3114                                BVDC_P_MIN(pNewPic->ulSourceHorizontalSize,  BFMT_1080I_WIDTH);
3115                }
3116
3117#if (!BVDC_P_SUPPORT_3D_VIDEO)
3118                /* (3) Handle stream larger than 720p.  Feeder will NOT be
3119                 * able to handle this, and halt the bvb downstream.  VDC will
3120                 * force a field output for this pictures.
3121                 * Two exceptions:
3122                 *   - PsF mode;
3123                 *   - 1080p24/25/30 pass-thru mode;
3124                 *   - Feeding using GFX surface;
3125                 * For MPG source, ulVertFreq is the max scanout frame rate; */
3126                if((BAVC_Polarity_eFrame == pNewPic->eSourcePolarity) &&
3127                   (pNewPic->ulSourceVerticalSize  > BFMT_720P_HEIGHT) &&
3128                   (BVDC_P_PSF_VERT_FREQ < hSource->ulVertFreq) &&
3129                   (!pNewPic->hSurface))
3130                {
3131                        BDBG_WRN(("MVD[%d] passing larger than 720p frame picture", hSource->eId));
3132                        pNewPic->eSourcePolarity = BAVC_Polarity_eTopField;
3133                }
3134#endif
3135
3136                /* (4) If interlaced stream vertical size must be even */
3137                if(BAVC_Polarity_eFrame != pNewPic->eSourcePolarity)
3138                {
3139                        /* Jira SW7405-4239: XMD might send odd width for special aspect ratio purpose
3140                           pNewPic->ulSourceHorizontalSize = pNewPic->ulSourceHorizontalSize & ~1; */
3141                        pNewPic->ulSourceVerticalSize   = pNewPic->ulSourceVerticalSize & ~1;
3142                }
3143        }
3144
3145        /* (4) Handle unknown color space.  In the cases of 'unknown', 'forbidden'
3146         * and 'reserved' values passed from MVD, we display the picture according
3147         * to its frame size, i.e. if frame size > 720x576, treat it as default
3148         * HD(BT.709) color; else treat it as NTSC or PAL SD. */
3149        if((BAVC_MatrixCoefficients_eFCC != pNewPic->eMatrixCoefficients) &&
3150           (BAVC_MatrixCoefficients_eSmpte_170M != pNewPic->eMatrixCoefficients) &&
3151           (BAVC_MatrixCoefficients_eSmpte_240M != pNewPic->eMatrixCoefficients) &&
3152           (BAVC_MatrixCoefficients_eItu_R_BT_709 != pNewPic->eMatrixCoefficients) &&
3153           (BAVC_MatrixCoefficients_eItu_R_BT_470_2_BG != pNewPic->eMatrixCoefficients))
3154        {
3155                const BVDC_Settings *pDefSetting = &hSource->hVdc->stSettings;
3156                if(pNewPic->ulSourceVerticalSize > BFMT_PAL_HEIGHT)
3157                {
3158                        pNewPic->eMatrixCoefficients = pDefSetting->eColorMatrix_HD;
3159                }
3160                else if(pNewPic->ulSourceVerticalSize > BFMT_480P_HEIGHT)
3161                {
3162                        pNewPic->eMatrixCoefficients = BAVC_MatrixCoefficients_eItu_R_BT_470_2_BG;
3163                }
3164                else
3165                {
3166                        pNewPic->eMatrixCoefficients = pDefSetting->eColorMatrix_SD;
3167                }
3168        }
3169
3170#ifdef BVDC_MPEG_SOURCE_MAD_DEBUG
3171        /* Note:
3172         * 1. if mvd passes frame to vdc, we need to be intelligent here;
3173         * 2. progressive sequence is true progressive material, so we don't need to
3174         *    detect and force scanout fields second hand for deinterlacer;
3175         * 3. interlaced sequence could decode into fields or frames; there is no harm
3176         *    to force scanout fields for deinterlacer; */
3177        if(!pNewPic->bCaptureCrc || pNewPic->bMute)
3178        {
3179                if((pNewPic->eSourcePolarity == BAVC_Polarity_eFrame) &&
3180                   !pNewPic->bStreamProgressive)
3181                {
3182                        if((hSource->stCurInfo.bDeinterlace) &&
3183#if (BVDC_P_SUPPORT_MAD_SRC_1080I)
3184                           (pNewPic->ulSourceVerticalSize   <= BFMT_1080I_HEIGHT)
3185#else
3186                           (pNewPic->ulSourceHorizontalSize <= BFMT_PAL_WIDTH) &&
3187                           (pNewPic->ulSourceVerticalSize   <= BFMT_PAL_HEIGHT)
3188#endif
3189                          )
3190                        {
3191                                BDBG_WRN(("Force scanout field instead of frame"));
3192                                /* force the field data source polarity */
3193                                pNewPic->eSourcePolarity = BVDC_P_NEXT_POLARITY(pCurPic->eSourcePolarity);
3194                        }
3195                }
3196        }
3197#endif
3198
3199        /* MVD should not give VDC a bad interrupt field somehing like
3200         * 5 or -1.  It should giving the interrupt that VDC interrupted them
3201         * with.   For mute pictures everything about field buffer can be
3202         * invalid, but not the interrupt field id. */
3203        BDBG_ASSERT(
3204                (BAVC_Polarity_eTopField==pNewPic->eInterruptPolarity) ||
3205                (BAVC_Polarity_eBotField==pNewPic->eInterruptPolarity) ||
3206                (BAVC_Polarity_eFrame   ==pNewPic->eInterruptPolarity));
3207
3208        /* Chroma pan-scan/src-clip for H.264 */
3209        if(pNewPic->eYCbCrType == BAVC_YCbCrType_e4_4_4)
3210        {
3211                BDBG_ERR(("eYCbCrType 4:4:4 is not supported by MFD!"));
3212                BDBG_ASSERT(0);
3213        }
3214
3215        /* Check if fields that are to be written to registers fit
3216         * within their field sizes. */
3217        if((!pNewPic->hSurface) &&
3218                (pNewPic->eSourcePolarity != BAVC_Polarity_eFrame) &&
3219            (!BVDC_P_SRC_VALIDATE_FIELD(MFD_0_LAC_CNTL, OUTPUT_FIELD_POLARITY,
3220                                        pNewPic->eSourcePolarity)))
3221        {
3222                BDBG_ERR(("eSourcePolarity is invalid"));
3223                pNewPic->eSourcePolarity = BAVC_Polarity_eTopField;
3224        }
3225
3226        /* Muted channel doesn't need to check the following things! */
3227        if(!pNewPic->bMute)
3228        {
3229                if(!BVDC_P_SRC_VALIDATE_FIELD(MFD_0_LAC_CNTL, CHROMA_TYPE,
3230                                                   pNewPic->eYCbCrType - BAVC_YCbCrType_e4_2_0))
3231                {
3232                        BDBG_ERR(("eYCbCrType is invalid"));
3233                        pNewPic->eYCbCrType = BAVC_YCbCrType_e4_2_0;
3234                }
3235
3236                if(!BVDC_P_SRC_VALIDATE_FIELD(MFD_0_LAC_CNTL, CHROMA_INTERPOLATION,
3237                                                   pNewPic->eChrominanceInterpolationMode))
3238                {
3239                        BDBG_ERR(("eChrominanceInterpolationMode is invalid"));
3240                        pNewPic->eChrominanceInterpolationMode = BAVC_InterpolationMode_eField;
3241                }
3242
3243                if((!pNewPic->hSurface) &&
3244                        !BVDC_P_SRC_VALIDATE_FIELD(MFD_0_LUMA_NMBY, VALUE, pNewPic->ulLuminanceNMBY))
3245                {
3246                        BDBG_ERR(("ulLuminanceNMBY is invalid: %d", pNewPic->ulLuminanceNMBY));
3247                        pNewPic->ulLuminanceNMBY = BVDC_P_SRC_FIELD_DATA_MASK(MFD_0_LUMA_NMBY, VALUE,
3248                                                                          pNewPic->ulLuminanceNMBY);
3249                }
3250
3251                if((!pNewPic->hSurface) &&
3252                        !BVDC_P_SRC_VALIDATE_FIELD(MFD_0_CHROMA_NMBY, VALUE, pNewPic->ulChrominanceNMBY))
3253                {
3254                        BDBG_ERR(("ulChrominanceNMBY is invalid: %d", pNewPic->ulChrominanceNMBY));
3255                        pNewPic->ulChrominanceNMBY = BVDC_P_SRC_FIELD_DATA_MASK(MFD_0_CHROMA_NMBY, VALUE,
3256                                                                            pNewPic->ulLuminanceNMBY);
3257                }
3258
3259                /* Only support BAVC_ChromaLocation_eType0 to BAVC_ChromaLocation_eType3 for now */
3260                if(pNewPic->eMpegType > BAVC_ChromaLocation_eType3)
3261                {
3262                        BDBG_ERR(("eMpegType is invalid"));
3263                        pNewPic->eMpegType = BAVC_MpegType_eMpeg2;
3264
3265                }
3266        }
3267
3268        /* Check if there are general changes from previous pictures. */
3269        if(BVDC_P_FIELD_DIFF(pNewPic, pCurPic, bMute) ||
3270           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, ulSourceHorizontalSize) ||
3271           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, ulSourceVerticalSize) ||
3272           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, ulDisplayHorizontalSize) ||
3273           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, ulDisplayVerticalSize) ||
3274           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eOrientation) ||
3275           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, uiSampleAspectRatioX) ||
3276           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, uiSampleAspectRatioY) ||
3277           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eAspectRatio) ||
3278           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, bValidAfd) ||
3279           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, ulAfd) ||
3280           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, eBarDataType) ||
3281           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, ulTopLeftBarValue) ||
3282           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, ulBotRightBarValue) ||
3283           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, bStreamProgressive) ||
3284           BVDC_P_FIELD_DIFF(pNewPic, pCurPic, bIgnoreCadenceMatch))
3285        {
3286                hSource->bPictureChanged = true;
3287
3288                BDBG_MSG(("bMute changes: %d->%d", pCurPic->bMute, pNewPic->bMute));
3289                BDBG_MSG(("ulSourceHorizontalSize changes: %d->%d", pCurPic->ulSourceHorizontalSize, pNewPic->ulSourceHorizontalSize));
3290                BDBG_MSG(("ulSourceVerticalSize changes: %d->%d", pCurPic->ulSourceVerticalSize, pNewPic->ulSourceVerticalSize));
3291                BDBG_MSG(("ulDisplayHorizontalSize changes: %d->%d", pCurPic->ulDisplayHorizontalSize, pNewPic->ulDisplayHorizontalSize));
3292                BDBG_MSG(("ulDisplayVerticalSize changes: %d->%d", pCurPic->ulDisplayVerticalSize, pNewPic->ulDisplayVerticalSize));
3293                BDBG_MSG(("eOrientation changes: %d->%d", pCurPic->eOrientation, pNewPic->eOrientation));
3294                BDBG_MSG(("uiSampleAspectRatioX changes: %d->%d", pCurPic->uiSampleAspectRatioX, pNewPic->uiSampleAspectRatioX));
3295                BDBG_MSG(("uiSampleAspectRatioY changes: %d->%d", pCurPic->uiSampleAspectRatioY, pNewPic->uiSampleAspectRatioY));
3296                BDBG_MSG(("eAspectRatio changes: %d->%d", pCurPic->eAspectRatio, pNewPic->eAspectRatio));
3297                BDBG_MSG(("bValidAfd changes: %d->%d", pCurPic->bValidAfd, pNewPic->bValidAfd));
3298                BDBG_MSG(("ulAfd changes: %d->%d", pCurPic->ulAfd, pNewPic->ulAfd));
3299                BDBG_MSG(("eBarDataType changes: %d->%d", pCurPic->eBarDataType, pNewPic->eBarDataType));
3300                BDBG_MSG(("ulTopLeftBarValue changes: %d->%d", pCurPic->ulTopLeftBarValue, pNewPic->ulTopLeftBarValue));
3301                BDBG_MSG(("ulBotRightBarValue changes: %d->%d", pCurPic->ulBotRightBarValue, pNewPic->ulBotRightBarValue));
3302                BDBG_MSG(("bIgnoreCadenceMatch changes: %d->%d", pCurPic->bIgnoreCadenceMatch, pNewPic->bIgnoreCadenceMatch));
3303        }
3304
3305        /* I -> P, or P -> I, for non-muted pictures. */
3306        if((pNewPic->eSourcePolarity | BAVC_Polarity_eBotField) !=
3307           (pCurPic->eSourcePolarity | BAVC_Polarity_eBotField))
3308        {
3309                hSource->bPictureChanged = true;
3310                hSource->bRasterChanged  = true;
3311                hSource->stCurInfo.stDirty.stBits.bInputFormat = BVDC_P_DIRTY;
3312                BDBG_MSG(("mpeg source raster change: old %d -> new %d", pCurPic->eSourcePolarity, pNewPic->eSourcePolarity));
3313        }
3314
3315        /* Check if anything wrong with mvd field. */
3316#if (BDBG_DEBUG_BUILD)
3317        BVDC_P_Source_PrintPicture(hSource, pCurPic, pNewPic);
3318#endif
3319
3320        return;
3321}
3322
3323/***************************************************************************
3324 * Application calls this function at every interrupt to set source info.
3325 *
3326 * Called to pass infomation from MVD to VDC.  For non-mpeg source
3327 * pNewPic will be NULL.   The data is use to build for the next
3328 * display vsync (or possibly queue up).
3329 * pvSourceHandle is (BVDC_Source_Handle).
3330 *
3331 */
3332void BVDC_Source_MpegDataReady_isr
3333        ( void                            *pvSourceHandle,
3334          int                              iParm2,
3335          void                            *pvMvdField )
3336{
3337        uint32_t i;
3338        BVDC_Source_Handle hSource = (BVDC_Source_Handle)pvSourceHandle;
3339        BVDC_Window_Handle hWindow;
3340        BRDC_Slot_Handle hSlot;
3341        BRDC_List_Handle hList;
3342        BAVC_MVD_Field stNewPic;
3343        BAVC_MVD_Field *pCurPic;
3344        BAVC_MVD_Field *pNewPic = &stNewPic;
3345        uint32_t ulOldEntries;
3346        BVDC_P_Source_DirtyBits *pCurDirty, *pOldDirty;
3347        bool bBuildBoth = false;
3348        uint32_t ulPictureIdx = 0;
3349        uint32_t ulSubRulEntries = 0;
3350        BRDC_Slot_Handle hSlotSlave = NULL;
3351        BRDC_List_Handle hListSlave = NULL;
3352        BVDC_P_ListInfo stMasterList, stList;
3353        BRDC_Trigger eTrigger = 0;
3354        uint32_t ulMosaicCount = 0;
3355        uint32_t ulMosaicWindows = 0;
3356        uint32_t ulComboTrigBitMask = 0; /* for combined triggers */
3357        bool bNoScanout = false; /* for PsF */
3358        BVDC_P_Source_Info *pNewInfo = &hSource->stNewInfo;
3359        BVDC_P_Source_Info *pCurInfo = &hSource->stCurInfo;
3360        BAVC_Polarity       ePrePolarity;
3361
3362        BDBG_ENTER(BVDC_Source_MpegDataReady_isr);
3363        BSTD_UNUSED(iParm2);
3364
3365        /* Casting to get parms */
3366        BDBG_OBJECT_ASSERT(hSource, BVDC_SRC);
3367        BDBG_OBJECT_ASSERT(hSource->hVdc, BVDC_VDC);
3368        pCurDirty = &hSource->stCurInfo.stDirty;
3369
3370        /* Make sure the BKNI enter/leave critical section works. */
3371        BDBG_ASSERT(0 == hSource->hVdc->ulInsideCs);
3372        hSource->hVdc->ulInsideCs++;
3373
3374        /* We should not even get the Gfx or analog source here. */
3375        BDBG_ASSERT(BVDC_P_SRC_IS_MPEG(hSource->eId));
3376        pCurPic = &hSource->stPrevMvdField;
3377        *pNewPic = *(BAVC_MVD_Field*)pvMvdField;
3378
3379        hSource->ulMosaicFirstUnmuteRectIndex = 0;
3380        hSource->bMosaicFirstUnmuteRectIndexSet = false;
3381
3382        /* Update source user info before using pCurInfo */
3383        BVDC_P_Source_UpdateSrcState_isr(hSource);
3384
3385#if BVDC_P_SUPPORT_MOSAIC_MODE
3386        if(hSource->stCurInfo.bMosaicMode)
3387        {
3388                /* re-order pic list for z-order */
3389                uint32_t          i = 0;
3390                BAVC_MVD_Field   *pOldCurPic, *pOldPrevPic;
3391                BAVC_MVD_Field   *pNewCurPic, *pNewPrevPic;
3392
3393                /* Loop through old pic list */
3394                pOldPrevPic = pNewPic;
3395                pOldCurPic = pOldPrevPic->pNext;
3396                while(pOldCurPic && (++i < hSource->ulMosaicCount))
3397                {
3398                        if(hSource->aucMosaicZOrder[pOldCurPic->ulChannelId] <
3399                           hSource->aucMosaicZOrder[pOldPrevPic->ulChannelId])
3400                        {
3401                                /* Find an out of order pic */
3402                                BDBG_MSG(("Src[%d] Find out of order tile: Chan[%d]: %d, Chan[%d]: %d",
3403                                        hSource->eId, pOldPrevPic->ulChannelId,
3404                                        hSource->aucMosaicZOrder[pOldPrevPic->ulChannelId],
3405                                        pOldCurPic->ulChannelId,
3406                                        hSource->aucMosaicZOrder[pOldCurPic->ulChannelId]));
3407
3408                                /* remove pOldCurPic from list */
3409                                pOldPrevPic->pNext = pOldCurPic->pNext;
3410                                BDBG_MSG(("Src[%d] Remove Chan: %d from list",
3411                                        hSource->eId, pOldCurPic->ulChannelId));
3412
3413                                /* Loop through new pic list */
3414                                pNewPrevPic = NULL;
3415                                pNewCurPic = pNewPic;
3416                                while(pNewCurPic &&
3417                                        (hSource->aucMosaicZOrder[pOldCurPic->ulChannelId] >
3418                                         hSource->aucMosaicZOrder[pNewCurPic->ulChannelId]))
3419                                {
3420                                        pNewPrevPic = pNewCurPic;
3421                                        pNewCurPic = pNewCurPic->pNext;
3422                                }
3423
3424                                /* Find the new position for pOldCurPic */
3425                                if(pNewPrevPic == NULL)
3426                                {
3427                                        /* Add pOldCurPic back to beginning of list */
3428                                        pOldCurPic->pNext = pNewPic;
3429                                        pNewPic = pOldCurPic;
3430                                }
3431                                else
3432                                {
3433                                        /* Add pOldCurPic back to list between pNewPrevPic and pNewCurPic */
3434                                        pNewPrevPic->pNext = pOldCurPic;
3435                                        pOldCurPic->pNext = pNewCurPic;
3436                                }
3437
3438                        }
3439                        else
3440                        {
3441                                pOldPrevPic = pOldCurPic;
3442                        }
3443
3444                        pOldCurPic = pOldPrevPic->pNext;
3445                }
3446
3447        }
3448#endif
3449
3450#if (BVDC_P_SUPPORT_3D_INDEP_SRC_CLIP)
3451        if((pNewPic->eOrientation == BFMT_Orientation_e3D_LeftRight) &&
3452            pNewPic->pEnhanced)
3453        {
3454                BAVC_MVD_Field   *pEnhanced;
3455
3456                pEnhanced = (BAVC_MVD_Field *)pNewPic->pEnhanced;
3457                if(pEnhanced->eOrientation == BFMT_Orientation_eLeftRight_Enhanced)
3458                {
3459                        /* Set eOrientation to BFMT_Orientation_eLeftRight_Enhanced
3460                         * to distinguish from regular BFMT_Orientation_e3D_LeftRight */
3461                        pNewPic->eOrientation = BFMT_Orientation_eLeftRight_Enhanced;
3462                }
3463        }
3464#endif
3465
3466#if (BVDC_P_SUPPORT_3D_VIDEO)
3467        /* bOrientationOverride only valid when original
3468         * orientation from XVD is 2D */
3469        if(pNewPic->eOrientation == BFMT_Orientation_e2D)
3470        {
3471                if(pCurInfo->bOrientationOverride)
3472                {
3473                        if(pCurInfo->eOrientation == BFMT_Orientation_e3D_OverUnder)
3474                        {
3475                                pNewPic->ulSourceVerticalSize  = pNewPic->ulSourceVerticalSize / 2;
3476                                pNewPic->ulDisplayVerticalSize = pNewPic->ulDisplayVerticalSize / 2;
3477                        }
3478                        else if(pCurInfo->eOrientation == BFMT_Orientation_e3D_LeftRight)
3479                        {
3480                                pNewPic->ulSourceHorizontalSize  = pNewPic->ulSourceHorizontalSize / 2;
3481                                pNewPic->ulDisplayHorizontalSize = pNewPic->ulDisplayHorizontalSize / 2;
3482                        }
3483                        pNewPic->eOrientation = pCurInfo->eOrientation;
3484                }
3485        }
3486        else if(pNewPic->eOrientation == BFMT_Orientation_e3D_OverUnder)
3487        {
3488                pNewPic->ulSourceVerticalSize  = pNewPic->ulSourceVerticalSize / 2;
3489                pNewPic->ulDisplayVerticalSize = pNewPic->ulDisplayVerticalSize / 2;
3490        }
3491        else if((pNewPic->eOrientation == BFMT_Orientation_e3D_LeftRight))
3492        {
3493                pNewPic->ulSourceHorizontalSize  = pNewPic->ulSourceHorizontalSize / 2;
3494                pNewPic->ulDisplayHorizontalSize = pNewPic->ulDisplayHorizontalSize / 2;
3495        }
3496#endif
3497
3498        /* H & V size alignment */
3499        /* Jira SW7405-4239: XMD might send odd width for special aspect ratio purpose
3500          pNewPic->ulSourceHorizontalSize = pNewPic->ulSourceHorizontalSize & ~1; */
3501        pNewPic->ulSourceVerticalSize   = pNewPic->ulSourceVerticalSize & ~1;
3502
3503        /* PsF: check if need to scanout; also store the scanout state for the
3504                next isr's scanout decision; */
3505        if(hSource->stCurInfo.bPsfEnable)
3506        {
3507                bool bPsfSrc =
3508                        (BFMT_720P_HEIGHT     <= pNewPic->ulSourceVerticalSize) &&
3509                        (BAVC_Polarity_eFrame == pNewPic->eSourcePolarity)       &&
3510                        (BAVC_FrameRateCode_e30 >= pNewPic->eFrameRateCode);
3511
3512                /* if user just turns on PsF, but decoder is in pause mode(bRepeat=true),
3513                   we still need to scan out for the first time;
3514                   if 1080p source repeats, don't scanout;
3515                   if last 1080p frame was scaned out and not in 1080p pass-thru (<=30Hz),
3516                   don't scanout for this time; */
3517                bNoScanout = (hSource->bPsfScanout) ||
3518                        (!pCurDirty->stBits.bPsfMode &&
3519                          pNewPic->bPictureRepeatFlag &&
3520                          bPsfSrc);
3521
3522                /* to keep src/win state machine moving, don't drop too many frames; */
3523                if(bNoScanout)
3524                {
3525                        if(++hSource->ulDropFramesCnt > 3)
3526                        {
3527                                bNoScanout = false;
3528                                hSource->ulDropFramesCnt = 0;
3529                                BDBG_MSG(("Mfd%d drops 4 1080p frames in a roll; Resume scanout!", hSource->eId));
3530                        }
3531                }
3532                else
3533                {
3534                        hSource->ulDropFramesCnt = 0;
3535                }
3536
3537                /* 1080p PsF scanout RUL must chop the RUL size to protect itself! */
3538                hSource->bPsfScanout =
3539                        !bNoScanout &&
3540                         bPsfSrc  &&
3541                        (hSource->ulDispVsyncFreq > BVDC_P_PSF_VERT_FREQ);
3542
3543                /* PsF: the source vertical freq is the frame rate (for frame capture) */
3544                if(hSource->bPsfScanout)
3545                {
3546                        uint32_t ulVertFreq;
3547
3548                        switch(pNewPic->eFrameRateCode)
3549                        {
3550                        case BAVC_FrameRateCode_e23_976:
3551                                ulVertFreq = 2397;
3552                                break;
3553                        case BAVC_FrameRateCode_e24:
3554                                ulVertFreq = 24 * BFMT_FREQ_FACTOR;
3555                                break;
3556                        case BAVC_FrameRateCode_e25:
3557                                ulVertFreq = 25 * BFMT_FREQ_FACTOR;
3558                                break;
3559                        case BAVC_FrameRateCode_e29_97:
3560                                ulVertFreq = 2997;
3561                                break;
3562                        case BAVC_FrameRateCode_e30:
3563                                ulVertFreq = 30 * BFMT_FREQ_FACTOR;
3564                                break;
3565                        default: /* shouldn't be here! */
3566                                BDBG_WRN(("=== Something is in doubt!"));
3567                                BDBG_WRN(("ulSourceVerticalSize = %d", pNewPic->ulSourceVerticalSize));
3568                                BDBG_WRN(("eSourcePolarity        = %d", pNewPic->eSourcePolarity));
3569                                BDBG_WRN(("eFrameRateCode      = %d", pNewPic->eFrameRateCode));
3570                                BDBG_WRN(("Ignore stream frame rate. Use PsF %d Hz",
3571                                        BVDC_P_PSF_VERT_FREQ/BFMT_FREQ_FACTOR));
3572                                BDBG_WRN(("==="));
3573                                ulVertFreq = BVDC_P_PSF_VERT_FREQ;
3574                        }
3575
3576                        if(hSource->ulVertFreq != ulVertFreq)
3577                        {
3578                                hSource->ulVertFreq = ulVertFreq;
3579                                hSource->bRasterChanged = true;
3580                        }
3581                }
3582                else if(!bPsfSrc)
3583                {
3584                        hSource->ulVertFreq = hSource->ulDispVsyncFreq;
3585                }
3586        }
3587        /* PsF: if user disables PsF, skip one new scanout to avoid MFD hang; */
3588        else if(hSource->bPsfScanout)
3589        {
3590                hSource->bPsfScanout = false;
3591                bNoScanout = true;
3592                pCurDirty->stBits.bPsfMode  = BVDC_P_CLEAN;
3593                BDBG_MSG(("MFD[%d] disables PsF! Skip a new scanout to avoid MFD hang.", hSource->eId));
3594        }
3595
3596        /* to avoid display/gfx flickering caused by the nop src RUL due to the
3597           field swap on the artificial triggers, we need to
3598           build RUL for the field swapped slot; */
3599        if(hSource->bPrevFieldSwap != hSource->bFieldSwap)
3600        {
3601                BDBG_MSG(("MFD[%d] bFieldSwap[%d->%d]!", hSource->eId,
3602                        hSource->bPrevFieldSwap, hSource->bFieldSwap));
3603
3604                /* field swap: this is the next real interrupt to come */
3605                pNewPic->eInterruptPolarity =
3606                        BVDC_P_NEXT_POLARITY(pNewPic->eInterruptPolarity);
3607
3608                /* update prev flag */
3609                hSource->bPrevFieldSwap = hSource->bFieldSwap;
3610        }
3611
3612        /* validate the input data structure; */
3613        BVDC_P_Source_ValidateMpegData_isr(hSource, pNewPic, pCurPic);
3614
3615        if(true == hSource->bFreshRateMismatch)
3616        {
3617                ePrePolarity = pCurPic->eSourcePolarity;
3618
3619                pNewPic->eSourcePolarity = (ePrePolarity == BAVC_Polarity_eTopField) ?
3620                        BAVC_Polarity_eBotField : BAVC_Polarity_eTopField;
3621        }
3622
3623        /* Update the format information for MPEG */
3624        if(hSource->bPictureChanged)
3625        {
3626                const BFMT_VideoInfo *pNewFmtInfo;
3627                const BFMT_VideoInfo *pCurFmtInfo;
3628                uint32_t ulNewPicFrmRate;
3629                bool bNewPicInterlaced;
3630                uint32_t ulSourceHorizontalSize, ulSourceVerticalSize;
3631
3632                ulSourceHorizontalSize = pNewPic->ulSourceHorizontalSize;
3633                ulSourceVerticalSize   = pNewPic->ulSourceVerticalSize;
3634
3635#if (BVDC_P_SUPPORT_3D_VIDEO)
3636                if((pNewPic->eOrientation == BFMT_Orientation_e3D_LeftRight))
3637                {
3638                        ulSourceHorizontalSize  = ulSourceHorizontalSize * 2;
3639                }
3640                else if(pNewPic->eOrientation == BFMT_Orientation_e3D_OverUnder)
3641                {
3642                        ulSourceVerticalSize  = ulSourceVerticalSize * 2;
3643                }
3644#endif
3645
3646                ulNewPicFrmRate = s_aulFrmRate[BVDC_P_MIN(BVDC_P_MAX_FRM_RATE_CODE, pNewPic->eFrameRateCode)];
3647                bNewPicInterlaced = (BAVC_Polarity_eFrame != pNewPic->eSourcePolarity);
3648
3649                /* retain last rate if framerate is unknown. */
3650                if(BAVC_FrameRateCode_eUnknown != pNewPic->eFrameRateCode)
3651                {
3652                        hSource->ulStreamVertFreq = ulNewPicFrmRate << (!pNewPic->bStreamProgressive);
3653                }
3654
3655                pCurFmtInfo = (BFMT_VideoFmt_eMaxCount == hSource->stExtVideoFmtInfo.eVideoFmt)?
3656                        &(hSource->stExtVideoFmtInfo) : pCurInfo->pFmtInfo;
3657
3658                if((!BVDC_P_EQ_DELTA(ulSourceHorizontalSize, pCurFmtInfo->ulDigitalWidth, BVDC_P_MPEG_FMT_DELTA)) ||
3659                   (!BVDC_P_EQ_DELTA(ulSourceVerticalSize, pCurFmtInfo->ulDigitalHeight, BVDC_P_MPEG_FMT_DELTA)) ||
3660                   (!BVDC_P_EQ_DELTA(ulNewPicFrmRate, pCurFmtInfo->ulVertFreq >> pCurFmtInfo->bInterlaced, BVDC_P_MPEG_FMT_DELTA)) ||
3661                   (bNewPicInterlaced != pCurFmtInfo->bInterlaced))
3662                {
3663                        /* src video format changed. try to match an enumerated video format */
3664                        for(i = 0; i < BVDC_P_MPEG_FMT_COUNT; i++)
3665                        {
3666                                pNewFmtInfo = BFMT_GetVideoFormatInfoPtr(s_aeMpegToFmt[i]);
3667                                if((BVDC_P_EQ_DELTA(ulSourceHorizontalSize, pNewFmtInfo->ulDigitalWidth, BVDC_P_MPEG_FMT_DELTA)) &&
3668                                   (BVDC_P_EQ_DELTA(ulSourceVerticalSize, pNewFmtInfo->ulDigitalHeight, BVDC_P_MPEG_FMT_DELTA)) &&
3669                                   (BVDC_P_EQ_DELTA(ulNewPicFrmRate, pNewFmtInfo->ulVertFreq >> pNewFmtInfo->bInterlaced, BVDC_P_MPEG_FMT_DELTA)) &&
3670                                   (bNewPicInterlaced == pNewFmtInfo->bInterlaced))
3671                                {
3672                                        break;
3673                                }
3674                        }
3675
3676                        if(BVDC_P_MPEG_FMT_COUNT == i)
3677                        {
3678                                BFMT_VideoFmt  eVFmtCode;
3679
3680                                /* non-enumerated mpeg video format, will return stExtVideoFmtInfo as callback */
3681                                hSource->stExtVideoFmtInfo.eVideoFmt = BFMT_VideoFmt_eMaxCount;
3682                                hSource->stExtVideoFmtInfo.ulDigitalWidth = ulSourceHorizontalSize;
3683                                hSource->stExtVideoFmtInfo.ulDigitalHeight = ulSourceVerticalSize;
3684                                hSource->stExtVideoFmtInfo.ulVertFreq = ulNewPicFrmRate << bNewPicInterlaced;
3685                                hSource->stExtVideoFmtInfo.bInterlaced = bNewPicInterlaced;
3686
3687                                /* approximate video Fmt code for VDC internal use only */
3688                                if (bNewPicInterlaced)
3689                                {
3690                                        eVFmtCode = (((ulSourceHorizontalSize <= BFMT_NTSC_WIDTH) &&
3691                                                                  (ulSourceVerticalSize   <= BFMT_NTSC_HEIGHT)) ?
3692                                                                 BFMT_VideoFmt_eNTSC :
3693                                                                 ((ulSourceHorizontalSize <= BFMT_PAL_WIDTH) &&
3694                                                                  (ulSourceVerticalSize   <= BFMT_PAL_HEIGHT)) ?
3695                                                                 BFMT_VideoFmt_ePAL_G :
3696                                                                 BFMT_VideoFmt_e1080i);
3697                                }
3698                                else
3699                                {
3700                                        eVFmtCode = (((ulSourceHorizontalSize <= BFMT_480P_WIDTH) &&
3701                                                                  (ulSourceVerticalSize   <= BFMT_480P_HEIGHT)) ?
3702                                                                 BFMT_VideoFmt_e480p :
3703                                                                 ((ulSourceHorizontalSize <= BFMT_576P_WIDTH) &&
3704                                                                  (ulSourceVerticalSize   <= BFMT_576P_HEIGHT)) ?
3705                                                                 BFMT_VideoFmt_e576p_50Hz :
3706                                                                 ((ulSourceHorizontalSize <= BFMT_720P_WIDTH) &&
3707                                                                  (ulSourceVerticalSize   <= BFMT_720P_HEIGHT)) ?
3708                                                                 BFMT_VideoFmt_e720p :
3709                                                                 BFMT_VideoFmt_e1080p);
3710                                }
3711                                pNewFmtInfo = BFMT_GetVideoFormatInfoPtr(eVFmtCode);
3712
3713                                BDBG_MSG(("MPEG[%d] changes to non-enumerated video fmt: w %d, h %d, Frmrate %d/100, bInterlaced %d ",
3714                                        hSource->eId, ulSourceHorizontalSize, ulSourceVerticalSize,
3715                                        ulNewPicFrmRate, bNewPicInterlaced? 1 : 0));
3716                        }
3717                        else
3718                        {
3719                                /* this is used later as deciding which formatInfo to send with callback */
3720                                hSource->stExtVideoFmtInfo.eVideoFmt = pNewFmtInfo->eVideoFmt;
3721                        }
3722
3723                        /* this is an enumerated video format */
3724                        BVDC_P_BUF_MSG(("MPEG[%d] Format change %s -> %s", hSource->eId,
3725                                pCurInfo->pFmtInfo->pchFormatStr, pNewFmtInfo->pchFormatStr));
3726
3727                        /* for BVDC_Source_GetSize support: need original size  */
3728                        hSource->stExtVideoFmtInfo.ulWidth = ulSourceHorizontalSize;
3729                        hSource->stExtVideoFmtInfo.ulHeight = ulSourceVerticalSize;
3730
3731                        /* Start the new format: this is only used for VDC internally for certain decision,
3732                         * might not have every thing accurate */
3733                        pCurInfo->pFmtInfo      = pNewInfo->pFmtInfo = pNewFmtInfo;
3734
3735                        /* Get vdc base fmt information */
3736                        pCurInfo->pVdcFmt       = pNewInfo->pVdcFmt  =
3737                                        BVDC_P_GetFormatInfoPtr_isr(pNewFmtInfo);
3738
3739                        /* Format changes, so set dirty to rebuild RUL. */
3740                        pCurDirty->stBits.bInputFormat = BVDC_P_DIRTY;
3741
3742                        /* inform next ApplyChanges to copy activated isr setting into new info */
3743                        hSource->stIsrInfo.stActivated.stBits.bInputFormat = BVDC_P_DIRTY;
3744                }
3745        }
3746
3747        hSource->eNextFieldId   = pNewPic->eInterruptPolarity;
3748        hSource->eNextFieldIntP = pNewPic->eInterruptPolarity;
3749
3750        /* MosaicMode: the frame rate tracking channel will set it later; */
3751        if(hSource->stCurInfo.bMosaicMode)
3752        {
3753                hSource->eFrameRateCode = BAVC_FrameRateCode_eUnknown;
3754                hSource->eMatrixCoefficients = BAVC_MatrixCoefficients_eUnknown;
3755        }
3756        else
3757        {
3758                hSource->eFrameRateCode = pNewPic->eFrameRateCode;
3759                hSource->eMatrixCoefficients = pNewPic->eMatrixCoefficients;
3760        }
3761
3762        if((hSource->stCurInfo.pfGenericCallback) &&
3763           (hSource->bCaptureCrc      ||
3764            pCurDirty->stBits.bInputFormat   ||
3765            hSource->bDeferSrcPendingCb ||
3766            (pCurDirty->stBits.bAddWin && hSource->stCurInfo.eResumeMode) ||
3767            (pCurPic->bMute && !pNewPic->bMute)))
3768        {
3769                BVDC_Source_CallbackData *pCbData = &hSource->stSourceCbData;
3770                BVDC_Source_DirtyBits *pCbDirty = &pCbData->stDirty;
3771
3772                /* Clear dirty bits */
3773                BVDC_P_CB_CLEAN_ALL_DIRTY(pCbDirty);
3774
3775                /* Issue src pending call back when shutdown BVN completed. */
3776                if(hSource->bDeferSrcPendingCb)
3777                {
3778                        BVDC_P_Source_CheckAndIssueCallback(hSource, pCbDirty);
3779                }
3780
3781                /* Make sure the callback happen at least once, on first
3782                 * installation of callback to report the current status. */
3783                if(pCurDirty->stBits.bGenCallback)
3784                {
3785                        pCbDirty->bActive     = BVDC_P_DIRTY;
3786                        pCbDirty->bFmtInfo    = BVDC_P_DIRTY;
3787                        hSource->bDeferSrcPendingCb = true;
3788                }
3789                else if((pCurDirty->stBits.bInputFormat) ||
3790                   (pCurDirty->stBits.bAddWin && hSource->stCurInfo.eResumeMode) ||
3791                   (pCurPic->bMute && !pNewPic->bMute))
3792                {
3793                        /* defer it until all windows are shutdown!
3794                         * Note, if input format changes, the next vsync will show window
3795                         * shutdown dirty bits;
3796                         * Only when all its windows shutdown dirty bits are cleared;
3797                         * is it safe to callback source pending; */
3798                        hSource->bDeferSrcPendingCb = hSource->stCurInfo.eResumeMode;
3799                        pCbDirty->bFmtInfo       = pCurDirty->stBits.bInputFormat;
3800                }
3801
3802                /* 7401 & beyond MFD supports field-accurate CRC checking on demand.
3803                 * Note: when a picture is required to capture CRC, its RUL is executed one
3804                 *       vsync later; and its CRC computation is completed at end of that
3805                 *       picture, i.e. another vsync later! So we use the stored key flag
3806                 *       to callback the captured CRC; */
3807                if(hSource->bCaptureCrc)
3808                {
3809                        pCbDirty->bCrcValue = true;
3810
3811                        /* update CRC readings */
3812                        BVDC_P_Feeder_GetCrc_isr(hSource->hMpegFeeder, hSource->hVdc->hRegister, pCbData);
3813                }
3814
3815                /* callback only if something changed */
3816                if(BVDC_P_CB_IS_DIRTY(pCbDirty))
3817                {
3818                        /* Update Callback data */
3819                        pCbData->bActive  = !pNewPic->bMute;
3820                        pCbData->pFmtInfo = ((BFMT_VideoFmt_eMaxCount == hSource->stExtVideoFmtInfo.eVideoFmt)?
3821                                                                 &(hSource->stExtVideoFmtInfo) : hSource->stCurInfo.pFmtInfo);
3822
3823                        hSource->stCurInfo.pfGenericCallback(
3824                                hSource->stCurInfo.pvGenericParm1,
3825                                hSource->stCurInfo.iGenericParm2, (void*)pCbData);
3826                        BDBG_MSG(("MPEG[%d] callBack: VideoFmtCode %d ",
3827                                          hSource->eId, pCbData->pFmtInfo->eVideoFmt));
3828                }
3829        }
3830
3831        /* if the compositor is in slip2lock transition, clean up syncslip display RUL
3832           to avoid sync-slipped VFD overwrite error in case source/display _isr are
3833           called in reverse order; */
3834        if(hSource->hSyncLockCompositor && hSource->hSyncLockCompositor->ulSlip2Lock)
3835        {
3836                BDBG_OBJECT_ASSERT(hSource->hSyncLockCompositor, BVDC_CMP);
3837                BDBG_OBJECT_ASSERT(hSource->hSyncLockCompositor->hDisplay, BVDC_DSP);
3838
3839                /* Check if we're doing frame.  If we're doing frame we're use a topfield
3840                 * slot to trigger the frame slot in source isr for sycn lock. */
3841                if(BAVC_Polarity_eFrame == hSource->eNextFieldIntP)
3842                {
3843                        BVDC_P_CMP_NEXT_RUL(hSource->hSyncLockCompositor, BAVC_Polarity_eTopField);
3844                        hSlot = BVDC_P_CMP_GET_SLOT(hSource->hSyncLockCompositor, BAVC_Polarity_eTopField);
3845                        hList = BVDC_P_CMP_GET_LIST(hSource->hSyncLockCompositor, BAVC_Polarity_eTopField);
3846                }
3847                else
3848                {
3849                        /* Get the approriate slot/list for building RUL. */
3850                        BVDC_P_CMP_NEXT_RUL(hSource->hSyncLockCompositor, hSource->eNextFieldIntP);
3851                        hSlot = BVDC_P_CMP_GET_SLOT(hSource->hSyncLockCompositor, hSource->eNextFieldIntP);
3852                        hList = BVDC_P_CMP_GET_LIST(hSource->hSyncLockCompositor, hSource->eNextFieldIntP);
3853                }
3854
3855                /* Reset the RUL entry count and build synclock display RUL! */
3856                BRDC_Slot_UpdateLastRulStatus_isr(hSlot, hList, false);
3857                BRDC_List_SetNumEntries_isr(hList, 0);
3858                BVDC_P_ReadListInfo_isr(&stList, hList);
3859
3860                BVDC_P_Compositor_BuildSyncLockRul_isr(hSource->hSyncLockCompositor, &stList, hSource->eNextFieldIntP);
3861
3862                /* Updated lists count */
3863                BVDC_P_WriteListInfo_isr(&stList, hList);
3864
3865                if(BAVC_Polarity_eFrame != hSource->eNextFieldIntP)
3866                {
3867                        BRDC_Slot_Handle hOtherSlot = BVDC_P_CMP_GET_SLOT(hSource->hSyncLockCompositor,
3868                                BVDC_P_NEXT_POLARITY(hSource->eNextFieldIntP));
3869                        BRDC_List_Handle hOtherList = BVDC_P_CMP_GET_LIST(hSource->hSyncLockCompositor,
3870                                BVDC_P_NEXT_POLARITY(hSource->eNextFieldIntP));
3871                        BVDC_P_ListInfo   stOtherList;
3872
3873                        BRDC_Slot_UpdateLastRulStatus_isr(hOtherSlot, hOtherList, false);
3874                        BRDC_List_SetNumEntries_isr(hOtherList, 0);
3875                        BVDC_P_ReadListInfo_isr(&stOtherList, hOtherList);
3876
3877                        BVDC_P_Compositor_BuildSyncLockRul_isr(hSource->hSyncLockCompositor,
3878                                &stOtherList, BVDC_P_NEXT_POLARITY(hSource->eNextFieldIntP));
3879
3880                        BVDC_P_WriteListInfo_isr(&stOtherList, hOtherList);
3881                        BRDC_Slot_SetCachedList_isr(hOtherSlot, hOtherList);
3882                }
3883
3884                /* SWAP: Program the hw, to setup the nEntries for the slot with this
3885                 * new RUL. */
3886                BRDC_Slot_SetCachedList_isr(hSlot, hList);
3887
3888                /* clear the flag */
3889                hSource->hSyncLockCompositor->ulSlip2Lock = 0;
3890                BDBG_MSG(("Src[%d] intP%d clears ulSlip2Lock", hSource->eId, hSource->eNextFieldIntP));
3891        }
3892
3893        /* Get the approriate slot/list for building RUL. */
3894        BVDC_P_SRC_NEXT_RUL(hSource, hSource->eNextFieldId);
3895        hSlot = BVDC_P_SRC_GET_SLOT(hSource, hSource->eNextFieldId);
3896        hList = BVDC_P_SRC_GET_LIST(hSource, hSource->eNextFieldId);
3897
3898        BRDC_Slot_UpdateLastRulStatus_isr(hSlot, hList, true);
3899
3900        /* Reset the RUL entry count and build RUL for backend! */
3901        BRDC_List_SetNumEntries_isr(hList, 0);
3902
3903        /* PsF: prefix a NOP RUL at head of PIP source RUL for robustness purpose;
3904                sync-slipped mpg source isr will only build capture side RUL; if 1080p
3905                PsF scanout is on, robustness RUL will simply chop the RUL size to the
3906                NOP minmum; */
3907        if(hSource->bPsfScanout && !hSource->hSyncLockCompositor)
3908        {
3909                BVDC_P_BuildNoOpsRul_isr(hList);
3910                BVDC_P_ReadListInfo_isr(&stMasterList, hList);
3911                stMasterList.ulPsfMark = (uint32_t)(stMasterList.pulCurrent - stMasterList.pulStart);
3912                stList.ulPsfMark = stMasterList.ulPsfMark;
3913        }
3914        else
3915        {
3916                BVDC_P_ReadListInfo_isr(&stMasterList, hList);
3917        }
3918        stMasterList.bMasterList = true;
3919        stList.bMasterList = true;
3920
3921        /* MosaicMode: picture list
3922         * ------------------------
3923         * 1. each picture represents a channel (with channel id) of mosaic list;
3924         * 2. picture list is sorted in ascending order by DM; shall we validate?
3925         * 3. existing channel needs to be captured into he correct location, according to
3926         *    the channel id (equivalent to rectangle id), into the cap buffer;
3927         * 3. missing channel (closed channel) simply results in no scanout/capture; but we
3928         *    need to use ClearRect to clear its corresponding mosaic rectangle at CMP;
3929         * 4. missing channel also means ulPictureIdx != ulChannelId;
3930         *    ulPictureIdx = 0 means to build master RUL, while ulPictureIdx > 0 means to
3931         *    build slave RUL; we can also assume ulPictureIdx <= ulChannelId;
3932         * 5. what if the first picture has ulChannelId != 0, or > ulMosaicCount?
3933         * 6. need to make sure ulChannelId < BAVC_MOSAIC_MAX;
3934         * 7. if the last picture ulChannelId < ulMosaicCount, ClearRect for the rest;
3935         */
3936        do
3937        {
3938                bool  bBuiltCanvasCtrlWithWin = false;
3939
3940        #define BDC_P_LIST_SEL(master, slave, idx)   ((0 == (idx))? (master) : (slave))
3941
3942                /* get the old num of entries */
3943                BRDC_List_GetNumEntries_isr(BDC_P_LIST_SEL(hList, hListSlave, ulPictureIdx), &ulOldEntries);
3944
3945                /* validate the next input data structure; */
3946                if(ulPictureIdx)
3947                {
3948                        BVDC_P_Source_ValidateMpegData_isr(hSource, pNewPic, pCurPic);
3949                }
3950
3951#if BVDC_P_SUPPORT_MOSAIC_MODE
3952                /* make sure channel id is valid */
3953                BDBG_ASSERT(pNewPic->ulChannelId < BAVC_MOSAIC_MAX);
3954
3955                if(!hSource->bMosaicFirstUnmuteRectIndexSet)
3956                {
3957                        if(!pNewPic->bMute)
3958                        {
3959                                hSource->ulMosaicFirstUnmuteRectIndex = ulPictureIdx;
3960                                hSource->bMosaicFirstUnmuteRectIndexSet = true;
3961                        }
3962                }
3963#endif
3964
3965                /* update windows that connected to this source, including user info,
3966                 * destroy related state and disconnecting from source */
3967                for(i = 0; i < BVDC_P_MAX_WINDOW_COUNT; i++)
3968                {
3969                        /* SKIP: If it's just created or inactive no need to build ruls. */
3970                        if(!hSource->ahWindow[i] ||
3971                                BVDC_P_STATE_IS_CREATE(hSource->ahWindow[i]) ||
3972                                BVDC_P_STATE_IS_INACTIVE(hSource->ahWindow[i]))
3973                        {
3974                                continue;
3975                        }
3976
3977                        hWindow = hSource->ahWindow[i];
3978                        BDBG_OBJECT_ASSERT(hWindow, BVDC_WIN);
3979
3980                        /* Non_MosaicMode window skips; */
3981                        if(ulPictureIdx && !hWindow->stCurInfo.bMosaicMode)
3982                        {
3983                                continue;
3984                        }
3985
3986                        BDBG_OBJECT_ASSERT(hWindow->hCompositor, BVDC_CMP);
3987                        BDBG_OBJECT_ASSERT(hWindow->hCompositor->hDisplay, BVDC_DSP);
3988
3989                        /* Vec format switch, executed the last force trigger from sync-lock
3990                         * display's slot.  It's in the middle of format change, no need to
3991                         * serve this interrupt. Clean up all source slots to be safe. */
3992                        if((BVDC_P_ItState_eActive != hWindow->hCompositor->hDisplay->eItState) &&
3993                           ((hWindow->hCompositor->hSyncLockSrc == hSource) ||
3994                                (hWindow->hCompositor->hForceTrigPipSrc == hSource)))
3995                        {
3996                                BVDC_P_Source_CleanupSlots_isr(hSource);
3997                                BDBG_MSG(("Synclocked display switches format. Clean up MFD[%d] slots!",
3998                                        hSource->eId));
3999                                goto MpegDataReady_isr_Done;
4000                        }
4001
4002                        /* for user-defined real-time Aspect Ratio Correction, we need
4003                         * to validate the user settings by _isr functions; if the check
4004                         * fails, we ignore those settings. */
4005                        BVDC_P_Window_ValidateRects_isr(hSource->ahWindow[i], pNewPic);
4006
4007                        /* MosaicMode: don't adjust DstRect; only adj sub-rects SrcCnt and SclOut; */
4008                        if((0 == ulPictureIdx)
4009#if BVDC_P_SUPPORT_MOSAIC_MODE
4010                                ||
4011                            (hWindow->stCurInfo.bMosaicMode &&
4012                             (pNewPic->ulChannelId < hWindow->stCurInfo.ulMosaicCount) &&
4013                             (hSource->bPictureChanged ||
4014                              BVDC_P_FIELD_DIFF(&hWindow->stCurInfo.astMosaicRect[pNewPic->ulChannelId],
4015                                               &hWindow->stCurInfo.astMosaicRect[pCurPic->ulChannelId], ulWidth) ||
4016                              BVDC_P_FIELD_DIFF(&hWindow->stCurInfo.astMosaicRect[pNewPic->ulChannelId],
4017                                               &hWindow->stCurInfo.astMosaicRect[pCurPic->ulChannelId], ulHeight)))
4018#endif
4019                           )
4020                        {
4021                                uint32_t ulRectIdx;
4022
4023                                /* MosaicMode: if the 1st picture's channel id exceeds mosaic count, we still
4024                                   need to adjust the rectangle for scanout; capture can drain it; so take
4025                                   mosaic rect 0; */
4026#if BVDC_P_SUPPORT_MOSAIC_MODE
4027                                if(pNewPic->ulChannelId >= hWindow->stCurInfo.ulMosaicCount)
4028                                {
4029                                        ulRectIdx = 0;
4030                                }
4031                                else
4032#endif
4033                                {
4034                                        ulRectIdx = pNewPic->ulChannelId;
4035                                }
4036
4037                                /* in mosaic mode, even if bPictureChanged==false, we still need to
4038                                 * do initMuteRect or AdjustRectangles, because mosaic pic size might
4039                                 * be diff from prev mosaic pic */
4040                                if(pNewPic->bMute)
4041                                {
4042                                        /* If source is muted, VDC will ignore rectangle clipping */
4043                                        if(hSource->bPictureChanged || hSource->stCurInfo.bMosaicMode)
4044                                        {
4045                                                BVDC_P_Window_InitMuteRec_isr(hSource->ahWindow[i],
4046                                                        hWindow->hCompositor->stCurInfo.pFmtInfo, pNewPic, ulRectIdx);
4047                                        }
4048                                }
4049                                else
4050                                {
4051                                        BVDC_P_Window_AdjustRectangles_isr(hSource->ahWindow[i], pNewPic, NULL,
4052                                                ulRectIdx);
4053                                }
4054                        }
4055                }
4056
4057                if(!pNewPic->bCaptureCrc || pNewPic->bMute)
4058                {
4059                        /* Get the source display rectangle. Combine the user pan-scan info
4060                         * from all the window that uses this source */
4061                        if((0 == ulPictureIdx) || pCurDirty->stBits.bRecAdjust)
4062                        {
4063                                BVDC_P_Source_GetScanOutRect_isr(hSource, pNewPic, NULL, &hSource->stScanOut);
4064                        }
4065
4066                        BVDC_P_Feeder_SetMpegInfo_isr(hSource->hMpegFeeder,
4067                                hSource->stCurInfo.ulMuteColorYCrCb, pNewPic, &hSource->stScanOut);
4068                }
4069                else
4070                {
4071                        BVDC_P_Rect stScanOut;
4072
4073                        /* if requested to capture CRC, feed the full size picture;
4074                         * Note, we don't care the display quality in this case; */
4075                        stScanOut.lLeft = 0;
4076                        stScanOut.lLeft_R = 0;
4077                        stScanOut.lTop = 0;
4078                        stScanOut.ulWidth  = pNewPic->ulSourceHorizontalSize & ~1;
4079                        stScanOut.ulHeight = pNewPic->ulSourceVerticalSize & ~1;
4080
4081                        /* Get the source display rectangle. Combine the user pan-scan info
4082                         * from all the window that uses this source;
4083                         * Note, this is to avoid crashing BVN since some of downstream modules
4084                         * programming depend on this rectangle; */
4085                        BVDC_P_Source_GetScanOutRect_isr(hSource, pNewPic, NULL, &hSource->stScanOut);
4086                        BVDC_P_Feeder_SetMpegInfo_isr(hSource->hMpegFeeder,
4087                                hSource->stCurInfo.ulMuteColorYCrCb, pNewPic, &stScanOut);
4088                }
4089
4090                /* Now update base next picture to be display, for all windows
4091                 * connected to this source. */
4092                for(i = 0; i < BVDC_P_MAX_WINDOW_COUNT; i++)
4093                {
4094                        /* SKIP: If it's just created or inactive no need to build ruls. */
4095                        if(!hSource->ahWindow[i] ||
4096                                BVDC_P_STATE_IS_CREATE(hSource->ahWindow[i]) ||
4097                                BVDC_P_STATE_IS_INACTIVE(hSource->ahWindow[i]))
4098                        {
4099                                continue;
4100                        }
4101                        hWindow = hSource->ahWindow[i];
4102                        BDBG_OBJECT_ASSERT(hWindow, BVDC_WIN);
4103
4104#if BVDC_P_SUPPORT_MOSAIC_MODE
4105                        /* Non_MosaicMode window skips;
4106                           Note: simul mode, non-mosaic window needs to shrink capture size to
4107                           reduce bandwidth; */
4108                        if((ulPictureIdx > 1) &&
4109                           (!hWindow->stCurInfo.bMosaicMode ||
4110                            hWindow->stCurInfo.ulMosaicCount < pNewPic->ulChannelId))
4111                        {
4112                                continue;
4113                        }
4114
4115                        /* MosaicMode: count number of mosaic windows for combo trigger;
4116                           note that one of simul windows enables mosaic mode would require
4117                           combo trigger for the whole picture list; un-captured rects are
4118                           drained by CAP and need trigger to proceed to the next mosaic picture; */
4119                        if(hSource->stCurInfo.bMosaicMode && (ulPictureIdx == 0))
4120                        {
4121                                /* increment count to set combo trigger */
4122                                ulMosaicWindows++;
4123
4124                                /* get the maxim mosaic count among windows to config proper trigger; */
4125                                ulMosaicCount = BVDC_P_MAX(ulMosaicCount, hWindow->stCurInfo.ulMosaicCount);
4126                                ulComboTrigBitMask |= 1 << hWindow->stCurResource.hCapture->eTrig;
4127                                if(ulMosaicCount == hWindow->stCurInfo.ulMosaicCount)
4128                                {
4129                                        eTrigger = hWindow->stCurResource.hCapture->eTrig;
4130                                }
4131                        }
4132#endif
4133                        /* MosaicMode: need to pass the sub-window index to build Capture RUL; note here we only care master
4134                            RUL's exec status; */
4135                        /* PsF: no window write state change while no scanout; */
4136                        if(!bNoScanout)
4137                        {
4138                                BVDC_P_Window_Writer_isr(hSource->ahWindow[i], pNewPic, NULL,
4139                                        hSource->eNextFieldId, &stMasterList, ulPictureIdx);
4140                        }
4141
4142                        /* note: mfd rul is built together with other modules in the vnet in window */
4143                }
4144
4145                if(pCurDirty->stBits.bRecAdjust || hSource->bWait4ReconfigVnet)
4146                {
4147                        /* Gather window information after vnetmode is determined */
4148                        BVDC_P_Source_GetWindowVnetmodeInfo_isr(hSource);
4149                }
4150
4151                /* If this source is sync-lock with a compositor/vec we'll need to
4152                 * build RUL for that VEC, and CMP.
4153                 * Note, we need to handle field swap for captured sync-locked src to be displayed
4154                 * correctly. */
4155                /* MosaicMode: only build playback side RUL once for master RUL! */
4156                if(hSource->hSyncLockCompositor && (0 == ulPictureIdx))
4157                {
4158                        /* FIELDSWAP 4): swap again with reader to display correct polarity; */
4159                        BVDC_P_ReadListInfo_isr(&stList, hList);
4160                        BVDC_P_Compositor_BuildSyncSlipRul_isr(hSource->hSyncLockCompositor,
4161                                &stList, (hSource->bFieldSwap) ?
4162                                BVDC_P_NEXT_POLARITY(hSource->eNextFieldId) : hSource->eNextFieldId,
4163                                false /* bBuildCanvasCtrl */);
4164                        BVDC_P_WriteListInfo_isr(&stList, hList);
4165
4166                        /* PsF: mark the initial chop location; */
4167                        if(hSource->bPsfScanout)
4168                        {
4169                                stList.ulPsfMark = (uint32_t)(stList.pulCurrent - stList.pulStart);
4170                        }
4171                }
4172
4173                /* Read plist master ? slave ? */
4174                BVDC_P_ReadListInfo_isr(&stList, BDC_P_LIST_SEL(hList, hListSlave, ulPictureIdx));
4175
4176                /* For each window using this SOURCE, If the window is sync-lock to this
4177                 * source build both the Writer & Reader modules.  If it's slip that means
4178                 * somebody else already building the Reader we're only need to build the
4179                 * writer. */
4180                /* MosaicMode: simul-windows use combined capture triggers; */
4181                for(i = 0; i < BVDC_P_MAX_WINDOW_COUNT; i++)
4182                {
4183                        /* SKIP: If it's just created or inactive no need to build ruls. */
4184                        if(!hSource->ahWindow[i] ||
4185                           BVDC_P_STATE_IS_CREATE(hSource->ahWindow[i]) ||
4186                           BVDC_P_STATE_IS_INACTIVE(hSource->ahWindow[i]))
4187                        {
4188                                continue;
4189                        }
4190
4191                        hWindow = hSource->ahWindow[i];
4192                        BDBG_OBJECT_ASSERT(hWindow, BVDC_WIN);
4193
4194#if BVDC_P_SUPPORT_MOSAIC_MODE
4195                        /* Non_MosaicMode window skips; */
4196                        if((ulPictureIdx > 1) &&
4197                           (!hWindow->stCurInfo.bMosaicMode ||
4198                            hWindow->stCurInfo.ulMosaicCount < pNewPic->ulChannelId))
4199                        {
4200                                continue;
4201                        }
4202#endif
4203                        /* build both slots RUL's if interlaced src format and window state or mode is in
4204                         * the transition to workaround non-alternating trigger pattern;
4205                         * during vnet changes, build double RUL's to commit change
4206                         * and get rid of change's RUL footprint afterwards; */
4207                        bBuildBoth |= hWindow->stCurInfo.stDirty.stBits.bShutdown ||
4208                                hWindow->stCurInfo.stDirty.stBits.bReConfigVnet;
4209
4210                        /* if window is already shutdown, don't need to build the shutdown RUL again
4211                         * to avoid killing the next established window path in case of variable
4212                         * isr latency doesn't promptly remove it from the slot next time; */
4213                        if(BVDC_P_State_eShutDown != hWindow->stCurInfo.eWriterState)
4214                        {
4215                                /* in case we just got the sync-lock and the new locked cmp will has
4216                                 * slip to lock transition, then we know that the new synclock cmp
4217                                 * will build the window reader RUL in the next vsync to retain the
4218                                 * consistent timing based on the same vec, so we only need
4219                                 * to build writer side here; */
4220                                if(hWindow->bSyncLockSrc)
4221                                {
4222                                        /* MosaicMode: playback side only build RUL once!! */
4223                                        BVDC_P_Window_BuildRul_isr(hWindow, &stList, hSource->eNextFieldId,
4224                                                !bNoScanout,        /* writer*/
4225                                                /* MosaicMode: only need to program reader once; */
4226                                                (0 == ulPictureIdx) /* reader */,
4227                                                (0 == ulPictureIdx) /* CanvasCtrl */ );
4228                                        bBuiltCanvasCtrlWithWin = (0 == ulPictureIdx);
4229                                }
4230                                else
4231                                {
4232                                        BVDC_P_Window_BuildRul_isr(hWindow, &stList, hSource->eNextFieldId,
4233                                                !bNoScanout,  /* writer*/
4234                                                false         /* reader */,
4235                                                false         /* CanvasCtrl */ );
4236                                }
4237                        }
4238                }
4239
4240                /* build compositor convas ctrl after syncLock window RUL is built */
4241                if(hSource->hSyncLockCompositor && (0 == ulPictureIdx) && !bBuiltCanvasCtrlWithWin)
4242                {
4243                        BVDC_P_Compositor_BuildConvasCtrlRul_isr(hSource->hSyncLockCompositor, &stList);
4244                }
4245
4246                /* Update pList */
4247                BVDC_P_WriteListInfo_isr(&stList, BDC_P_LIST_SEL(hList, hListSlave, ulPictureIdx));
4248
4249                /* save the previous picture's CRC key flag, to be used on next vsync;
4250                 * update current pictures. */
4251                if(!pCurPic->bMute)
4252                {
4253                        hSource->bCaptureCrc  = pCurPic->bCaptureCrc;
4254                        hSource->stSourceCbData.ulIdrPicId   = pCurPic->ulIdrPicID;
4255                        hSource->stSourceCbData.lPicOrderCnt = pCurPic->int32_PicOrderCnt;
4256                        hSource->stSourceCbData.eSourcePolarity = pCurPic->eSourcePolarity;
4257                }
4258                else
4259                {
4260                        /* if muted, don't capture CRC! */
4261                        hSource->bCaptureCrc  = false;
4262                }
4263
4264                /* context swap:
4265                 * Note this may not be optimal but can avoid unnecessary bug and confusion later! */
4266                *pCurPic = *pNewPic;
4267
4268                /* reset flag */
4269                hSource->bPictureChanged = false;
4270                hSource->bRasterChanged = false;
4271
4272#if BVDC_P_SUPPORT_MOSAIC_MODE
4273                /* if combo trigger for the slave slot's trigger */
4274                if((ulMosaicWindows > 1) && (ulPictureIdx == 0))
4275                {
4276                        eTrigger = hSource->eCombTrigger;
4277
4278                        BRDC_SetComboTrigMode_isr(hSource->hVdc->hRdc, eTrigger, BRDC_ComboTrigMode_eAllTriggers);
4279                        BRDC_SetComboTriggers_isr(hSource->hVdc->hRdc, eTrigger, ulComboTrigBitMask);
4280                }
4281#else
4282                BSTD_UNUSED(ulComboTrigBitMask);
4283                BSTD_UNUSED(ulMosaicWindows);
4284#endif
4285
4286                /* increment picture index for the next round;
4287                   if input pictures are more than the mosaic count, drop it; */
4288                if(++ulPictureIdx >= ulMosaicCount)
4289                {
4290                        break;
4291                }
4292
4293                /* Exhaust the picture list; if input pictures are less than mosaic count,
4294                   ignore the extra mosaics;
4295                   Note: window shutdown process shall not loop since window state machine
4296                   relies on the RUL execution status;  */
4297                if(!(pNewPic = pNewPic->pNext) || bBuildBoth)
4298                {
4299                        break;
4300                }
4301
4302                /* if channel id is larger than mosaic count, ignore the rest of picture list */
4303                if(pNewPic->ulChannelId >= ulMosaicCount)
4304                {
4305                        break;
4306                }
4307
4308                /* Only mosaic mode can go beyond this point; do it once; */
4309                if(ulPictureIdx == 1)
4310                {
4311                        /* MosaicMode: get next slave slot and list */
4312                        BVDC_P_SRC_GET_NEXT_SLAVE_RUL_IDX(hSource);
4313                        hSlotSlave = hSource->hSlotSlave;
4314
4315                        /* Get the current slave list pointed by ulSlaveRulIdx */
4316                        hListSlave = hSource->ahListSlave[hSource->ulSlaveRulIdx];
4317
4318                        BDBG_ASSERT(hSlotSlave);
4319                        BDBG_ASSERT(hListSlave);
4320
4321                        /* Update the status of last executed RUL.
4322                         * Only need to check the master RUL exec status; */
4323                        BRDC_Slot_UpdateLastRulStatus_isr(hSlotSlave, hListSlave, false);
4324                        BRDC_List_SetNumEntries_isr(hListSlave, 0);
4325
4326                        /* clear the master flag to avoid building capture timestamp rul */
4327                        stList.bMasterList = false;
4328                }
4329
4330                /* config slave slot for the mosaics captures; */
4331                if(ulPictureIdx == 1)
4332                {
4333                        /* use capture trigger to drive mosaic slave-RULs; also a place holder of the
4334                         * count for the next slave RUL! */
4335                        BRDC_Slot_RulConfigSlaveTrigger_isr(hSlot, hSlotSlave, hList,
4336                                eTrigger, true);
4337
4338                        /* link to the slave RUL's header */
4339                        BRDC_List_RulSetSlaveListHead_isr(hList, hSlotSlave, hListSlave);
4340                }
4341                else
4342                {
4343                        uint32_t ulScrap;
4344
4345                        /* place holder to config count of next slave RUL */
4346                        BRDC_Slot_RulConfigSlaveTrigger_isr(hSlotSlave, hSlotSlave, hListSlave,
4347                                eTrigger, true);
4348
4349                        /* link to the next slave RUL */
4350                        ulScrap = BRDC_Slot_RulSetNextAddr_isr(hSlotSlave, hListSlave);
4351
4352                        /* calculate ulSubRulEntries */
4353                        BRDC_List_GetNumEntries_isr(hListSlave, &ulSubRulEntries);
4354                        ulSubRulEntries -= ulOldEntries + ulScrap;
4355
4356                        /* update config count with current slave RUL's size into the previous RUL's
4357                         * place holder; */
4358                        BRDC_Slot_RulConfigCount_isr((ulPictureIdx == 2) ? hSlot : hSlotSlave, ulSubRulEntries);
4359                }
4360        }       while(true);
4361
4362        /* Clear old dirty bits. */
4363        /* TODO: should we move this up, at least for vnet updating? */
4364        pOldDirty = &hSource->astOldDirty[hSource->eNextFieldId];
4365
4366        if((BVDC_P_IS_DIRTY(pOldDirty)) &&
4367           (!stMasterList.bLastExecuted))
4368        {
4369                BVDC_P_OR_ALL_DIRTY(pCurDirty, pOldDirty);
4370        }
4371
4372        /* Copy cur dirty bits to "old" and clear cur dirty bits. */
4373        *pOldDirty = *pCurDirty;
4374        BVDC_P_CLEAN_ALL_DIRTY(pCurDirty);
4375
4376        /* SWAP: Program the hw, to setup the nEntries for the slot with this new RUL. */
4377        /* MosaicMode: don't overwrite the first slot config of the RUL chain */
4378        if(ulPictureIdx >= 2)
4379        {
4380                /* chained sub-RULs tail: disable itself */
4381                BRDC_Slot_RulConfigSlaveListTail_isr(hSlotSlave, hListSlave);
4382
4383                /* calculate ulSubRulEntries */
4384                BRDC_List_GetNumEntries_isr(hListSlave, &ulSubRulEntries);
4385                ulSubRulEntries -= ulOldEntries;
4386
4387                /* update config count with current slave RUL's size into the previous RUL's
4388                 * place holder; */
4389                BRDC_Slot_RulConfigCount_isr((ulPictureIdx == 2)? hSlot : hSlotSlave, ulSubRulEntries);
4390
4391                /* flush slave RULs */
4392                BRDC_Slot_FlushCachedList_isr(hSlotSlave, hListSlave);
4393        }
4394
4395        /* Put on both slot for interlace */
4396        if(BAVC_Polarity_eFrame != hSource->eNextFieldId)
4397        {
4398                BRDC_Slot_Handle hOtherSlot = BVDC_P_SRC_GET_SLOT(hSource,
4399                        BVDC_P_NEXT_POLARITY(hSource->eNextFieldId));
4400
4401                /* PsF: build RUL to chop its own size! */
4402                if(hSource->bPsfScanout)
4403                {
4404                        /* PsF: interlaced slots need to config both; */
4405                        BRDC_Slot_RulConfigRulSize_isr(hSlot, hList, stList.ulPsfMark);
4406                        BRDC_Slot_RulConfigRulSize_isr(hOtherSlot, hList, stList.ulPsfMark);
4407                }
4408                /* Note: to flush the cached RUL only once, call the Dual function
4409                   instead of two individual slot functions; */
4410                BRDC_Slot_SetCachedListDual_isr(hSlot, hOtherSlot, hList);
4411        }
4412        else
4413        {
4414                /* PsF: build RUL to chop its own size! */
4415                if(hSource->bPsfScanout)
4416                {
4417                        BRDC_Slot_RulConfigRulSize_isr(hSlot, hList, stList.ulPsfMark);
4418                }
4419                BRDC_Slot_SetCachedList_isr(hSlot, hList);
4420        }
4421#if BVDC_P_SUPPORT_STG
4422        /* NRT STG host arm after the new RUL is installed to HW */
4423        if(hSource->hSyncLockCompositor &&
4424           (BVDC_P_DISPLAY_USED_STG(hSource->hSyncLockCompositor->hDisplay->eMasterTg)) &&
4425           (hSource->hSyncLockCompositor->hDisplay->stCurInfo.bStgNonRealTime))
4426        {
4427                BREG_Write32(hSource->hVdc->hRegister,
4428                        BCHP_VIDEO_ENC_STG_0_HOST_ARM + hSource->hSyncLockCompositor->hDisplay->ulStgRegOffset, 1);
4429        }
4430#endif
4431
4432MpegDataReady_isr_Done:
4433
4434        /* apply done event early for sync locked windows and windows with
4435           identical timing (has source driven by its compositor.  Fixes
4436           ApplyChanges taking more than one vsync to complete.
4437           Usually handled in BVDC_P_Window_UpdateState_isr() */
4438        for(i = 0; i < BVDC_P_MAX_WINDOW_COUNT; i++)
4439        {
4440                /* SKIP: If it's just created or inactive no need to build ruls. */
4441                if(!hSource->ahWindow[i] ||
4442                    BVDC_P_STATE_IS_CREATE(hSource->ahWindow[i]) ||
4443                    BVDC_P_STATE_IS_INACTIVE(hSource->ahWindow[i]))
4444                {
4445                        continue;
4446                }
4447
4448                hWindow = hSource->ahWindow[i];
4449                BDBG_OBJECT_ASSERT(hWindow, BVDC_WIN);
4450
4451                if(((hWindow->hCompositor->hSyncLockSrc == hSource) ||
4452                    (hWindow->hCompositor->hForceTrigPipSrc == hSource)) &&
4453                    (hWindow->bSetAppliedEventPending) &&
4454                        ((BVDC_P_IS_CLEAN(&hWindow->stCurInfo.stDirty)) ||
4455                    (hWindow->stCurInfo.stDirty.stBits.bSrcPending && !hWindow->stCurInfo.stDirty.stBits.bShutdown)))
4456                {
4457                        BKNI_SetEvent_isr(hWindow->hAppliedDoneEvent);
4458                        hWindow->bSetAppliedEventPending = false;
4459                        BDBG_MSG(("Window[%d] set apply done event", hWindow->eId));
4460                }
4461        }
4462
4463        hSource->hVdc->ulInsideCs--;
4464        BDBG_LEAVE(BVDC_Source_MpegDataReady_isr);
4465        return;
4466}
4467
4468/* End of File */
Note: See TracBrowser for help on using the repository browser.