source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/xvd/7552/bxvd_userdata.c

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

first commit

  • Property svn:executable set to *
File size: 47.7 KB
Line 
1/***************************************************************************
2 *         Copyright (c) 2004-2011, 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: bxvd_userdata.c $
11 * $brcm_Revision: Hydra_Software_Devel/123 $
12 * $brcm_Date: 12/1/11 2:50p $
13 *
14 * Module Description:
15 *       This module controls and returns the User Data coming in the stream
16 * and captured by the decoder.
17 *
18 * Revision History:
19 *
20 * $brcm_Log: /magnum/portinginterface/xvd/7401/bxvd_userdata.c $
21 *
22 * Hydra_Software_Devel/123   12/1/11 2:50p pblanco
23 * SW7425-1780: Previous checkin did not propagate queued value to AVC.
24 *
25 * Hydra_Software_Devel/122   12/1/11 1:12p pblanco
26 * SW7425-1780: Implemented picture id support for transcode userdata.
27 *
28 * Hydra_Software_Devel/121   7/20/11 3:04p davidp
29 * SW7420-2001: Reorder header file includes.
30 *
31 * Hydra_Software_Devel/120   4/30/10 1:43p pblanco
32 * SW7400-2753: Fix kernel oops when user data packet size exceeds maximum
33 * buffer size.
34 *
35 * Hydra_Software_Devel/119   3/25/10 11:50a pblanco
36 * SWGIGGSVIZIO-4: Added NULL pointer check before BKNI_Memcpy.
37 *
38 * Hydra_Software_Devel/118   3/18/10 11:44p pblanco
39 * SW3548-2845: Changed BXVD_P_Userdata_QueueRemove to
40 * BXVD_P_Userdata_QueueRemove_isr and changed its scope to static.
41 *
42 * Hydra_Software_Devel/117   3/13/10 10:53a davidp
43 * SW7400-2704: Userdaa header type nolong bit field.
44 *
45 * Hydra_Software_Devel/116   3/3/10 5:27p davidp
46 * SW7400-2704: Add SEI message frame packing support.
47 *
48 * Hydra_Software_Devel/115   2/25/10 4:24p nilesh
49 * SW7405-2993: XDM Merge
50 *
51 * Hydra_Software_Devel/114   2/18/10 3:54p pblanco
52 * SW7405-3939: Implemented and tested repeat first field fix.
53 *
54 * Hydra_Software_Devel/113   11/30/09 4:41p btosi
55 * SW7405-3245: added BXVD_DBG_* macros.  Map to either BDBG_INSTANCE_* or
56 * BDBG_* at compile.
57 *
58 * Hydra_Software_Devel/112   10/30/09 11:29a btosi
59 * SW7405-3257: added support for measuring execution times
60 *
61 * Hydra_Software_Devel/111   8/14/09 4:51p pblanco
62 * PR27168: Just check returned address value for 0, not the error return
63 * code. This is for compatibility with the single decode branch.
64 *
65 * Hydra_Software_Devel/110   8/14/09 10:44a pblanco
66 * PR27168: Check for an error from the offset to address convertion
67 * routine and return without enqueing the packet.
68 *
69 * Hydra_Software_Devel/109   7/23/09 2:57p pblanco
70 * PR27168: Changed decimal output in extended debugging messages to
71 * unsigned.
72 *
73 * Hydra_Software_Devel/108   7/23/09 11:07a pblanco
74 * PR27168: Remove unnecessary memory clear in read ISR.
75 *
76 * Hydra_Software_Devel/107   7/23/09 8:45a pblanco
77 * PR27168: Added "interpolated" PTS display to extra debugging output.
78 *
79 * Hydra_Software_Devel/106   7/22/09 1:47p pblanco
80 * PR27168: Added PTS to extra debugging output.
81 *
82 * Hydra_Software_Devel/105   2/4/09 9:01a pblanco
83 * PR51740: Remove extraneous BKNI_Free.
84 *
85 * Hydra_Software_Devel/104   1/21/09 2:02p nilesh
86 * PR45052: Converted BDBG_xxx to BDBG_INSTANCE_xxx calls to support
87 * multiple channels
88 *
89 * Hydra_Software_Devel/103   10/20/08 1:45p pblanco
90 * PR48063: Fix dead code error reported by Coverity.
91 *
92 * Hydra_Software_Devel/102   8/29/08 2:06p pblanco
93 * PR45230: Modify BXVD_Userdata_Close to support a critical section.
94 *
95 * Hydra_Software_Devel/101   7/31/08 4:33p pblanco
96 * PR45230: Check for queue overflow in read ISR and set
97 * bErrorBufferOverflow flag appropriately.
98 *
99 * Hydra_Software_Devel/100   7/29/08 10:25a pblanco
100 * PR45230: Moved static global error to the userdata context structure.
101 *
102 * Hydra_Software_Devel/99   7/11/08 2:56p pblanco
103 * PR29915: Fixed compiler warnings when built in PROXY mode
104 *
105 * Hydra_Software_Devel/98   7/1/08 11:55a pblanco
106 * PR44387: Removed code that allowed a callback with a NULL userdata
107 * pointer.
108 *
109 * Hydra_Software_Devel/97   6/16/08 1:20p pblanco
110 * PR29915: Added better error handling and recovery to enqueueing and
111 * read_isr routines.
112 *
113 * Hydra_Software_Devel/96   6/3/08 9:27a pblanco
114 * PR42910: Added handle type checking to externally visable APIs.
115 *
116 * Hydra_Software_Devel/95   5/21/08 2:51p pblanco
117 * PR42910: Add handle type to handle initialization.
118 *
119 * Hydra_Software_Devel/94   5/21/08 1:50p pblanco
120 * PR42910: Removed include of bxvd_userdata_priv.h. Its contents are now
121 * in bxvd_priv.h
122 *
123 * Hydra_Software_Devel/93   4/16/08 9:10a pblanco
124 * PR35059: Fixed most recent Coverity issues
125 *
126 * Hydra_Software_Devel/92   4/14/08 9:45a pblanco
127 * PR41311: Added settings argument to (currently unused) QueueRemove in
128 * code conditionalized for flattened userdata packets
129 *
130 * Hydra_Software_Devel/91   4/9/08 9:56a pblanco
131 * PR41311: Merge in Min's change from single decode branch.
132 *
133 * Hydra_Software_Devel/90   4/8/08 11:39a pblanco
134 * PR41311: Merged remainder of settable parameter changes from single
135 * decode branch
136 *
137 * Hydra_Software_Devel/89   4/7/08 7:08p pblanco
138 * PR41311: Merged parameter settability changes from single decode branch
139 *
140 * Hydra_Software_Devel/88   4/4/08 4:32p pblanco
141 * PR41311: Backed out queue item size change. Queue depth can still be
142 * adjusted
143 *
144 * Hydra_Software_Devel/87   4/3/08 4:33p pblanco
145 * PR41311: Made queue depth and item size runtime settable parameters
146 *
147 * Hydra_Software_Devel/86   3/12/08 11:39a pblanco
148 * PR40262: Fixed do/while loop logic error discovered by Thompson during
149 * a Klockwork run.
150 *
151 * Hydra_Software_Devel/85   1/8/08 2:35p pblanco
152 * PR38593: Added support for AVS userdata handling
153 *
154 * Hydra_Software_Devel/84   10/11/07 10:47a pblanco
155 * PR35991: Fixed missing deallocation in error path found by Coverity
156 *
157 * Hydra_Software_Devel/83   9/27/07 9:00a pblanco
158 * PR29915: Added VC1 header code
159 *
160 * Hydra_Software_Devel/82   9/19/07 8:47a pblanco
161 * PR35059: Fixed potential code problems found by Coverity
162 *
163 * Hydra_Software_Devel/81   9/14/07 9:21a btosi
164 * PR29915: removed BERR_TRACE from BXVD_P_Userdata_EnqueueDataPointer()
165 *
166 * Hydra_Software_Devel/80   9/12/07 9:26a pblanco
167 * PR29915: Added BERR_TRACE calls back where appropriate. Removed
168 * redundant BERR_Code declarations in a couple of functions.
169 *
170 * Hydra_Software_Devel/79   9/10/07 2:39p pblanco
171 * PR29915: Removed BERR_TRACE around all returns. A side effect of this
172 * macro caused errors
173 *
174 * Hydra_Software_Devel/78   9/10/07 1:04p pblanco
175 * PR34636: Increase size of user data item from 512 to 2048 for all
176 * platforms
177 *
178 * Hydra_Software_Devel/77   9/6/07 5:36p nilesh
179 * PR29915: Added BERR_TRACE wrapper around all return codes
180 *
181 * Hydra_Software_Devel/76   8/13/07 4:08p nilesh
182 * PR29915: Multi-decode merge to mainline
183 *
184 * Hydra_Software_Devel/xvd_PR29915_Rel_Mosaic_FW_API/2   7/25/07 1:37p nilesh
185 * PR29915: Cleaned up bxvd_priv.h and bxvd_vdec_info.h constants to match
186 * XVD coding style
187 *
188 * Hydra_Software_Devel/xvd_PR29915_Rel_Mosaic_FW_API/1   7/3/07 3:47p nilesh
189 * PR29915: bxvd_priv.h cleanup
190 *
191 * Hydra_Software_Devel/75   5/15/07 4:01p pblanco
192 * PR27168: Move pointer assignment to body of do loop in enqueue.
193 *
194 * Hydra_Software_Devel/74   5/14/07 3:36p pblanco
195 * PR27168: Fixed check for NULL next pointer in enqueue routine.
196 *
197 * Hydra_Software_Devel/73   4/11/07 1:34p pblanco
198 * PR27168: Changed BDBG_WRN messages to BDBG_MSG calls in
199 * EnqueueDataPointer.
200 *
201 * Hydra_Software_Devel/72   4/11/07 11:34a pblanco
202 * PR28732: Userdata read now returns a packet at a time instead of a
203 * flattened list. This insures that the proper userdata type is returned
204 * with the data.
205 *
206 * Hydra_Software_Devel/71   4/9/07 12:59p pblanco
207 * PR27168: Enhanced debugging output in userdata read routine.
208 *
209 * Hydra_Software_Devel/70   4/2/07 3:31p pblanco
210 * PR27168: Fixed typo in userdata content output debug message.
211 *
212 * Hydra_Software_Devel/69   3/29/07 3:03p pblanco
213 * PR27168: Cleaned up debug output and made it generally more useful.
214 *
215 * Hydra_Software_Devel/68   3/27/07 2:02p pblanco
216 * PR27168: Removed deprecated bxvd_mem.h include.
217 *
218 * Hydra_Software_Devel/67   2/21/07 9:12a pblanco
219 * PR26433: Set formatting to standard agreed upon within the XVD group on
220 * 2/20/07.
221 *
222 * Hydra_Software_Devel/66   2/20/07 1:46p pblanco
223 * PR27683: Use VDEC_FLAG_PTS_PRESENT instead of hardwired 0x20.
224 *
225 * Hydra_Software_Devel/65   2/15/07 3:51p pblanco
226 * PR27683: Added PTS and PTS valid flag to userdata.
227 *
228 * Hydra_Software_Devel/64   12/14/06 3:06p davidp
229 * PR25443: Copy userdata on longword aligned boundary.
230 *
231 * Hydra_Software_Devel/63   12/13/06 7:18p davidp
232 * PR25443: Read all currently queued data in BXVD_Userdata_Read_isr().
233 *
234 * Hydra_Software_Devel/62   12/12/06 3:02p davidp
235 * PR25443: Merge Simplified FW API branch into mainline
236 *
237 * Hydra_Software_Devel/61   12/11/06 1:21p pblanco
238 * PR26433: Added comments to code and cleaned up formatting.
239 *
240 * Hydra_Software_Devel/60   10/19/06 12:29p davidp
241 * PR25021: Add BSTD_UNUSED(xvdInterruptCallBack) to
242 * UninstallInterruptCallback routine.
243 *
244 * Hydra_Software_Devel/59   9/8/06 11:13a pblanco
245 * PR24149: Untested fix for occasional kernel error due to unaligned
246 * pointer.
247 *
248 * Hydra_Software_Devel/58   8/1/06 5:55p davidp
249 * PR22967: Return userdata to FW if app callback is not installed.
250 *
251 * Hydra_Software_Devel/57   7/26/06 1:01p davidp
252 * PR22967: Userdata buffers are now always returned to FW.
253 *
254 * Hydra_Software_Devel/56   7/21/06 12:02p pblanco
255 * PR22673: Fixed bug referencing the proper area for userdata memory.
256 *
257 * Hydra_Software_Devel/55   7/21/06 9:49a pblanco
258 * PR22673: Added userdata offset to address conversion code.
259 *
260 * Hydra_Software_Devel/54   7/18/06 12:11a nilesh
261 * PR22673: Code restructure for 97400, 97401 B0, and 97118
262 *
263 * Hydra_Software_Devel/PR22673/1   7/17/06 2:34p nilesh
264 * PR22673: Restructure on 97401
265 *
266 * Hydra_Software_Devel/53   7/6/06 9:40a pblanco
267 * PR21943: Fixed conditional compilation for 7401 B0, broken when
268 * conditionalizing for 7118.
269 *
270 * Hydra_Software_Devel/52   7/5/06 3:20p pblanco
271 * PR21943: Conditionalization for 7118
272 *
273 * Hydra_Software_Devel/51   6/15/06 4:06p davidp
274 * PR20017: Remove references to mmap'd FW heap
275 *
276 * Hydra_Software_Devel/50   6/14/06 9:19a pblanco
277 * PR20017: Insured that enqueue routine error path returns the userdata
278 * buffer to FW via the correct heap based on chip type and version.
279 *
280 * Hydra_Software_Devel/49   6/13/06 12:35p pblanco
281 * PR20017: Conditionalize buffer setup for B0
282 *
283 * Hydra_Software_Devel/48   6/13/06 9:48a pblanco
284 * PR20017: Make sure userdata handle is NULLed on close.
285 *
286 * Hydra_Software_Devel/47   6/9/06 6:25p davidp
287 * PR21846: Fixed compiler warnings caused by gcc option "-O3"
288 *
289 * Hydra_Software_Devel/46   6/9/06 1:16p pblanco
290 * PR20017: Removed unused parameters from uninstall callback function.
291 *
292 * Hydra_Software_Devel/45   5/26/06 1:54p davidp
293 * PR21740: Store userdata context in channel context, convert userdata
294 * addr using private memory heap info.
295 *
296 * Hydra_Software_Devel/44   5/9/06 3:00p pblanco
297 * PR19877: Added debugging messages to user data module.
298 *
299 * Hydra_Software_Devel/43   2/15/06 1:56p pblanco
300 * PR18545: Extended user data types for 7401/7400 in the same manner Mai
301 * did for 7411.
302 *
303 * Hydra_Software_Devel/42   2/14/06 12:59p pblanco
304 * PR19566: We no longer attempt to queue a NULL data pointer.
305 * BXVD_P_Userdata_EnqueueDataPointer now returns a
306 * BXVD_ERR_USERDATA_NONE in this case.
307 *
308 * Hydra_Software_Devel/41   1/26/06 4:03p davidp
309 * PR19123: Remove printf debug messages, clean up compiler warnings:
310 *
311 * Hydra_Software_Devel/40   1/18/06 3:18p davidp
312 * PR16792: Static FW buffers are part of FW Code heap, use proper heap
313 * for bmem address conversion routines.:
314 *
315 * Hydra_Software_Devel/39   1/18/06 1:41p pblanco
316 * PR19123: Modifications for 7400 port. Conditionally include proper
317 * bchp_740x.h file depending on platform.
318 *
319 * Hydra_Software_Devel/38   1/16/06 1:28p davidp
320 * PR16792: BXVD_Open now uses two heap pointers, one for FW code (2MB)
321 * the other for FW picture buffers.:
322 *
323 * Hydra_Software_Devel/37   1/10/06 10:07a pblanco
324 * PR16052: Added addistional error checking and recovery to enqueue data
325 * function.
326 *
327 * Hydra_Software_Devel/36   1/3/06 4:28p darnstein
328 * PR18545: Eliminate userdata_type enum for DSS. Simplify remaining
329 * enums. This was the consensus reached with David Erickson today, after
330 * consulting with Bill Fassl.
331 *
332 * Hydra_Software_Devel/35   12/23/05 10:02a pblanco
333 * PR18797: Fixed uninitialized variable issue.
334 *
335 * Hydra_Software_Devel/34   12/20/05 10:23a pblanco
336 * PR18545: Changed user data types to new definitions and added H264 &
337 * DSS recognition.
338 *
339 * Hydra_Software_Devel/33   12/14/05 9:59a pblanco
340 * PR16052: Changed install/uninstall callback functions to accept a
341 * standard BINT_CallbackFunc type.
342 *
343 * Hydra_Software_Devel/32   12/9/05 3:19p vsilyaev
344 * PR 18019: Fixed include files
345 *
346 * Hydra_Software_Devel/31   12/9/05 10:59a pblanco
347 * PR16052: Fix potential back to back buffer release problem in read
348 * code.
349 *
350 * Hydra_Software_Devel/30   12/8/05 12:59p pblanco
351 * PR16052: Increased queue depth from 64 to 128.
352 *
353 * Hydra_Software_Devel/29   12/8/05 10:33a pblanco
354 * PR16052: BXVD_P_EnqueueDataPointer now handles queue overflow condition
355 * properly.
356 *
357 * Hydra_Software_Devel/26   12/6/05 2:50p pblanco
358 * PR18411: Modified BXVD_Userdata_Read_isr so that user data buffers are
359 * returned properly to the firmware.
360 *
361 * Hydra_Software_Devel/25   12/5/05 3:41p pblanco
362 * PR16052: More debugging messages.
363 *
364 * Hydra_Software_Devel/24   12/5/05 9:55a pblanco
365 * PR16052: Restored byte swapping for little endian mode and added some
366 * BDBG_MSGs.
367 *
368 * Hydra_Software_Devel/22   11/28/05 3:48p pblanco
369 * PR16052: Incorporated Mai's latest changes to 7411 bxvd_userdata.c
370 *
371 * Hydra_Software_Devel/21   11/23/05 12:31p pblanco
372 * PR16052: Pre-holiday/power shutdown sanity check in.
373 *
374 * Hydra_Software_Devel/19   11/22/05 9:46a pblanco
375 * PR16052: Code changes required to user data after debugging with
376 * Brutus.
377 *
378 * Hydra_Software_Devel/18   11/18/05 12:36p pblanco
379 * PR16052: Make sure that install callback disables user data by default.
380 *
381 * Hydra_Software_Devel/17   11/18/05 9:23a pblanco
382 * PR16052: Added code to set field polarity and pulldown flags in user
383 * providedffer.
384 *
385 * Hydra_Software_Devel/12   11/14/05 2:47p pblanco
386 * PR16052: Temporarily remove assert checking for NULL user data pointer
387 * in BXVD_P_Userdata_EnqueueDataPointer.
388 *
389 * Hydra_Software_Devel/11   11/14/05 1:24p pblanco
390 * PR16052: More 7401 specific code changes.
391 *
392 * Hydra_Software_Devel/10   11/11/05 9:48a pblanco
393 * PR16052: Added channel handle argument to
394 * BXVD_P_Userdata_EnqueueDataPointer.
395 *
396 * Hydra_Software_Devel/9   11/11/05 7:27a pblanco
397 * PR16052: Added skeleton for BXVD_P_Userdata_EnqueueDataPointer so DM
398 * can begin integration.
399 *
400 * Hydra_Software_Devel/8   11/9/05 9:23a pblanco
401 * PR16052: Additional changes to converge on the 7401 model of user data
402 * acquisition.
403 *
404 * Hydra_Software_Devel/7   10/20/05 9:24p pblanco
405 * PR16052: Added brute force queue flush to user data enable.
406 *
407 * Hydra_Software_Devel/6   10/20/05 8:52p pblanco
408 * PR16052: Added enable API. TODO: flush queue before re-enabling
409 * callback
410 *
411 * Hydra_Software_Devel/5   10/7/05 3:29p pblanco
412 * PR16052: Ported existing 7411 code to the 7401 model as we know it
413 * today.
414 *
415 * Hydra_Software_Devel/4   9/21/05 5:44p davidp
416 * PR16052:  Add additional func parameter to BXVD_CallbackFunc
417 * definition.:
418 *
419 * Hydra_Software_Devel/3   8/23/05 10:22a pblanco
420 * PR16052: Removed include of bxvd_temp_defs.h
421 *
422 * Hydra_Software_Devel/2   7/7/05 4:13p pblanco
423 * PR16052: Check in after fixing CC problems.
424 *
425 * Hydra_Software_Devel/1   7/7/05 10:42a pblanco
426 * PR16052: Added
427 *
428 *
429 ***************************************************************************/
430#include "bstd.h"                                /* standard types */
431#include "bavc.h"                                /* for userdata */
432#include "bdbg.h"                                /* Dbglib */
433#include "bkni.h"                                /* malloc */
434#include "bxvd.h"
435#include "bxvd_platform.h"
436#include "bxvd_priv.h"
437#include "bxvd_userdata.h"
438#include "bxvd_vdec_info.h"
439
440BDBG_MODULE(BXVD_USERDATA);
441
442/* Set this to 1 to see a live dump of the user data. Use with caution as
443 * this will affect the timing of the callback.
444 */
445#define BXVD_USERDATA_EXTRA_DEBUG 0
446
447/*
448 * Set this to 0 to send each individual user data packet to the application.
449 * Normally, we flatten multiple packets into a single large packet and send
450 * that off to the application.
451 */
452#define BXVD_FLATTEN_USERDATA 0
453
454/*
455 * Set this to one to cause the read routine to return immediately upon
456 * detecting a user data type change. This must be used in conjunction
457 * with BXVD_FLATTEN_USERDATA = 1
458 */
459#define BXVD_BREAK_ON_TYPE_CHANGE 0
460
461/* Default settings. */
462static const BXVD_Userdata_Settings s_stUserdataDefaultSettings =
463{
464   (4 * 1024),   /* default 4 kbyte user data size */
465   BXVD_P_USERDATA_QUEUE_MAX,
466   BXVD_P_USERDATA_ITEM_SIZE
467};
468
469/* Initialize the userdata read queue */
470BERR_Code BXVD_P_Userdata_QueueInitialize(QUEUE_MGR *queue, BXVD_Userdata_Settings stUDSettings)
471{
472   int i;
473
474   BDBG_ENTER(BXVD_P_Userdata_QueueInitialize);
475
476#if BXVD_USERDATA_EXTRA_DEBUG
477   BKNI_Printf("<<< maxDataSize: %d >>>\n", stUDSettings.maxDataSize);
478   BKNI_Printf("<<< maxQueueDepth: %d >>>\n", stUDSettings.maxQueueDepth);
479   BKNI_Printf("<<< maxQueueItemSize: %d >>>\n", stUDSettings.maxQueueItemSize);
480#endif
481
482   queue->queue_data = (struct data *)BKNI_Malloc(stUDSettings.maxQueueDepth*sizeof(struct data));
483   if (queue->queue_data == NULL)
484      return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
485
486   BKNI_Memset(queue->queue_data, 0, stUDSettings.maxQueueDepth*sizeof(struct data));
487
488   for (i = 0; i < stUDSettings.maxQueueDepth; i++)
489   {
490      queue->queue_data[i].uUserData = (unsigned char *)BKNI_Malloc(stUDSettings.maxQueueItemSize*sizeof(unsigned char));
491      BKNI_Memset(queue->queue_data[i].uUserData, 0, stUDSettings.maxQueueItemSize);
492   }
493
494   queue->ulQueueDepth = 0;
495   queue->ulReadPtr = BXVD_P_USERDATA_QUEUE_START;
496   queue->ulWritePtr = BXVD_P_USERDATA_QUEUE_START;
497   queue->ulNextPtr = BXVD_P_USERDATA_QUEUE_START;
498
499   BDBG_LEAVE(BXVD_P_Userdata_QueueInitialize);
500   return BERR_SUCCESS;
501}
502
503
504/* Clear the userdata queue. Just calls queue initialize */
505BERR_Code BXVD_P_Userdata_QueueClear(QUEUE_MGR *queue, BXVD_Userdata_Settings stUDSettings)
506{
507   int i;
508   queue->ulQueueDepth = 0;
509   queue->ulReadPtr = BXVD_P_USERDATA_QUEUE_START;
510   queue->ulWritePtr = BXVD_P_USERDATA_QUEUE_START;
511   queue->ulNextPtr = BXVD_P_USERDATA_QUEUE_START;
512
513   for (i = 0; i < stUDSettings.maxQueueDepth; i++)
514      BKNI_Memset(queue->queue_data[i].uUserData, 0, stUDSettings.maxQueueItemSize);
515
516   return BERR_SUCCESS;
517}
518
519BERR_Code BXVD_P_Userdata_QueueDestroy(QUEUE_MGR *queue, BXVD_Userdata_Settings stUDSettings)
520{
521   int i;
522
523   queue->ulQueueDepth = 0;
524   queue->ulReadPtr = BXVD_P_USERDATA_QUEUE_START;
525   queue->ulWritePtr = BXVD_P_USERDATA_QUEUE_START;
526   queue->ulNextPtr = BXVD_P_USERDATA_QUEUE_START;
527
528   for (i = 0; i < stUDSettings.maxQueueDepth; i++)
529      BKNI_Free(queue->queue_data[i].uUserData);
530
531   if (queue->queue_data)
532      BKNI_Free(queue->queue_data);
533
534   return BERR_SUCCESS;
535}
536
537/***************************************************************************
538 *  {secret}
539 *  BXVD_P_Userdata_QueueInsert
540 *  Adds data to the specified circular queue
541 */
542BERR_Code BXVD_P_Userdata_QueueInsert(QUEUE_MGR *queue,
543                                      int protocol,
544                                      unsigned long ulUserDataAddr,
545                                      long          lUserDataSize,
546                                      unsigned long ulFlags,
547                                      unsigned long ulPulldown,
548                                      unsigned long ulPTS,
549                                      uint32_t uiDecodePictureId,
550                                      BXVD_Userdata_Settings stUDSettings)
551{
552   BDBG_ENTER(BXVD_P_Userdata_QueueInsert);
553
554   /* Make sure the queue pointers are valid */
555   if ((queue->ulWritePtr < BXVD_P_USERDATA_QUEUE_START) || 
556       (queue->ulWritePtr >= stUDSettings.maxQueueDepth))
557   {
558      return BERR_TRACE(BXVD_ERR_QUEUE_CORRUPTED);
559   }
560
561   /* Fill in the queue's next pointer */
562   queue->ulNextPtr = queue->ulWritePtr+1;
563
564   /* Wrap around */
565   if (queue->ulNextPtr == stUDSettings.maxQueueDepth)
566   {
567      queue->ulNextPtr = BXVD_P_USERDATA_QUEUE_START;
568   }
569
570   /* Check for queue overflow */
571   if (queue->ulNextPtr == queue->ulReadPtr)
572   {
573      return BERR_TRACE(BXVD_ERR_QUEUE_FULL);
574   }
575
576   /* Write value to queue */
577   queue->queue_data[queue->ulWritePtr].protocol = protocol;
578   queue->queue_data[queue->ulWritePtr].ulFlags = ulFlags;
579   queue->queue_data[queue->ulWritePtr].ulPulldown = ulPulldown;
580   queue->queue_data[queue->ulWritePtr].ulPTS = ulPTS;
581   queue->queue_data[queue->ulWritePtr].uiDecodePictureId = uiDecodePictureId;
582
583   BKNI_Memset((unsigned char *)(queue->queue_data[queue->ulWritePtr].uUserData),
584               0x0, 
585               stUDSettings.maxQueueItemSize);
586
587#if 0
588   BKNI_Printf("lUserDataSize: %ld\n", lUserDataSize);
589#endif
590
591   if (lUserDataSize > stUDSettings.maxQueueItemSize)
592   {
593      BKNI_Printf("lUserSataSize(%lu) > maxQueueItemSize(%d) Truncating to maxQueueItemSize and copying with bErrorBufferOverflow set to true\n",
594                  lUserDataSize, stUDSettings.maxQueueItemSize);
595      BKNI_Memcpy((unsigned char *)(queue->queue_data[queue->ulWritePtr].uUserData), 
596                  (void *)ulUserDataAddr,
597                  stUDSettings.maxQueueItemSize);
598      queue->ulWritePtr = queue->ulNextPtr;
599      queue->ulQueueDepth++;
600      return BERR_TRACE(BXVD_ERR_USERDATA_ITEM_TOO_LARGE);
601   }
602   else
603   {
604   BKNI_Memcpy((unsigned char *)(queue->queue_data[queue->ulWritePtr].uUserData), 
605               (void *)ulUserDataAddr,
606               lUserDataSize);
607   }
608
609   queue->ulWritePtr = queue->ulNextPtr;
610   queue->ulQueueDepth++;
611
612   return BERR_SUCCESS;
613}
614
615/***************************************************************************
616 *  {secret}
617 *  BXVD_P_Userdata_QueueRemove_isr
618 *  Remove next entry from specified circular queue.
619 */
620static BERR_Code BXVD_P_Userdata_QueueRemove_isr(QUEUE_MGR *queue,
621                                                 int *protocol,
622                                                 unsigned long *udp,
623                                                 unsigned long *ulFlags,
624                                                 unsigned long *ulPulldown,
625                                                 unsigned long *ulPTS,
626                                                 uint32_t *uiDecodePictureId,
627                                                 BXVD_Userdata_Settings stUDSettings)
628{
629   BDBG_ENTER(BXVD_P_Userdata_QueueRemove_isr);
630
631   /* Make sure there is data in the queue */
632   if (queue->ulReadPtr == queue->ulWritePtr)
633   {
634      return BXVD_ERR_QUEUE_EMPTY;
635   }
636
637
638   /* Check the queue pointers for validity */
639   if ((queue->ulWritePtr < BXVD_P_USERDATA_QUEUE_START) || 
640       (queue->ulWritePtr >= stUDSettings.maxQueueDepth))
641   {
642      return BERR_TRACE(BXVD_ERR_QUEUE_CORRUPTED);
643   }
644
645   /* Return the userdata information from the queue */
646   *protocol = queue->queue_data[queue->ulReadPtr].protocol;
647   *udp = (unsigned long)queue->queue_data[queue->ulReadPtr].uUserData;
648   *ulFlags = queue->queue_data[queue->ulReadPtr].ulFlags;
649   *ulPulldown = queue->queue_data[queue->ulReadPtr].ulPulldown;
650   *ulPTS = queue->queue_data[queue->ulReadPtr].ulPTS;
651   *uiDecodePictureId = queue->queue_data[queue->ulReadPtr].uiDecodePictureId;
652
653   /* Increment the userdata read pointer and decrement the depth */
654   queue->ulReadPtr++;
655   queue->ulQueueDepth--;
656
657   /* Check for wrap around */
658   if (queue->ulReadPtr == stUDSettings.maxQueueDepth)
659   {
660      queue->ulReadPtr = BXVD_P_USERDATA_QUEUE_START;
661   }
662
663   BDBG_LEAVE(BXVD_P_Userdata_QueueRemove_isr);
664   return BERR_SUCCESS;
665}
666
667/***************************************************************************
668 *  {secret}
669 * BXVD_P_Userdata_EnqueueDataPointer
670 */
671BERR_Code BXVD_P_Userdata_EnqueueDataPointer(BXVD_ChannelHandle hXvdCh,
672                                             int protocol,
673                                             unsigned long p_UserData,
674                                             unsigned long ulFlags,
675                                             unsigned long ulPulldown,
676                                             unsigned long ulPTS,
677                                             uint32_t uiDecodePictureId)
678{
679   BERR_Code rc = BERR_SUCCESS;
680   unsigned long ulUserDataAddr;
681   UD_HDR *pHdrInfo;
682
683   BDBG_ENTER(BXVD_P_Userdata_EnqueueDataPointer);
684
685   
686   /* Initialize global error to success */
687   if (hXvdCh->pUserData)
688      hXvdCh->pUserData->errForwardError = BERR_SUCCESS;
689
690   /*   
691    * If the global user data context pointer isn't initialized, return
692    * an error.
693    */
694   if (hXvdCh->pUserData == 0)
695   {
696      BXVD_DBG_MSG(hXvdCh, ("BXVD_P_Userdata_EnqueueDataPointer: not initialized"));
697      return BXVD_ERR_USERDATA_UNINITED;
698   }
699               
700   /*
701    * If the user data callback is disabled, return an error. This is actually
702    * more of a warning than an indication of something wrong in the userdata
703    * subsystem.
704    */
705   if (hXvdCh->pUserData->bCallbackEnabled == false)
706   {
707      BXVD_DBG_MSG(hXvdCh, ("BXVD_P_Userdata_EnqueueDataPointer: callback disabled"));
708      return BXVD_ERR_USERDATA_DISABLED;
709   }
710               
711   /* If no userdata callback is installed, return the buffer and signal an
712    * error.
713    */
714   if (hXvdCh->pUserData->fUserdataCallback_isr == NULL)
715   {
716      BXVD_DBG_MSG(hXvdCh, ("BXVD_P_Userdata_EnqueueDataPointer: callback not installed"));
717      return BXVD_ERR_USERDATA_DISABLED;
718   }
719
720   /*
721    * If the user data pointer is NULL return a no data error.
722    */
723   if (p_UserData == 0)
724   {
725      BXVD_DBG_MSG(hXvdCh, ("BXVD_P_Userdata_EnqueueDataPointer: no data"));
726      return BERR_TRACE(BXVD_ERR_USERDATA_NONE);
727   }
728
729
730   /*
731    * Get the protocol type and user data pointer from DM and convert it to
732    * a virtual address before enqueueing.
733    */
734   ulUserDataAddr = 0;
735   BXVD_P_CONVERT_UD_OFF2ADDR(hXvdCh->pUserData,
736                              p_UserData,
737                              &ulUserDataAddr);
738   if (ulUserDataAddr == 0)
739      return BERR_TRACE(BXVD_ERR_USERDATA_INVALID);
740
741
742   /* Loop through user data following the next pointer until the last
743    * (or a single) packet is found. We call the application UD callback
744    * each time a packet is found, converted and copied.
745    */
746   do
747   {
748      /* Extract the header information */
749      pHdrInfo = (UD_HDR *)ulUserDataAddr;
750      if (pHdrInfo == NULL)
751      {
752         BXVD_DBG_MSG(hXvdCh, ("BXVD_P_Userdata_EnqueueDataPointer: bad userdata pointer"));
753         return BXVD_ERR_USERDATA_INVALID;
754      }
755
756      /*
757       * Enqueue the data. The uiDecodePictureId member was added for transcode
758       * userdata support. Jira: SW7425-1780
759       */
760      rc = BXVD_P_Userdata_QueueInsert(&((hXvdCh->pUserData)->queue),
761                                       protocol,
762                                       ulUserDataAddr,
763                                       ((sizeof(UD_HDR)+((pHdrInfo->size+3))) & ~3), /* Make sure we copy long words, endianess issue */
764                                       ulFlags,
765                                       ulPulldown,
766                                       ulPTS,
767                                       uiDecodePictureId,
768                                       hXvdCh->pUserData->sUserdataSettings);
769      if (rc != BERR_SUCCESS)
770      {
771         BXVD_DBG_ERR(hXvdCh, ("Could not enqueue user data packet"));
772         hXvdCh->pUserData->errForwardError = rc;
773         goto doCallback;
774         /*return rc;*/
775      }
776                       
777      /* Get the next user data packet, if any */
778      pHdrInfo = (UD_HDR *)ulUserDataAddr;
779
780      if (pHdrInfo->next)
781      {
782         BXVD_P_CONVERT_UD_OFF2ADDR(hXvdCh->pUserData,
783                                    (unsigned long)pHdrInfo->next,
784                                    &ulUserDataAddr);
785         if (ulUserDataAddr == 0)
786            return BERR_TRACE(BXVD_ERR_USERDATA_INVALID);
787      }
788
789      if (pHdrInfo)
790      {
791         if (pHdrInfo->next)
792         {
793            BXVD_P_CONVERT_UD_OFF2ADDR(hXvdCh->pUserData,
794                                       (unsigned long)pHdrInfo->next,
795                                       &ulUserDataAddr);
796            if (ulUserDataAddr == 0)
797               return BERR_TRACE(BXVD_ERR_USERDATA_INVALID);
798         }
799      }
800   } while (pHdrInfo->next);
801
802doCallback:
803
804   /* Invoke application UD read callback */
805   if (hXvdCh->pUserData->fUserdataCallback_isr)
806   {
807      hXvdCh->pUserData->fUserdataCallback_isr(hXvdCh->pUserData->pParm1,
808                                               hXvdCh->pUserData->parm2);
809   }
810
811   BDBG_LEAVE(BXVD_P_Userdata_EnqueueDataPointer);
812   return rc;
813}
814
815/***************************************************************************
816 * Get userdata default settings. Currently this is only the default
817 * userdata buffer size (4K).
818 ***************************************************************************/
819BERR_Code BXVD_Userdata_GetDefaultSettings(BXVD_Userdata_Settings *pDefSettings)
820{
821   BDBG_ENTER(BXVD_Userdata_GetDefaultSettings);
822   BDBG_ASSERT(pDefSettings);
823               
824   *pDefSettings = s_stUserdataDefaultSettings;
825               
826   BDBG_LEAVE(BXVD_Userdata_GetDefaultSettings);
827   return BERR_SUCCESS;
828}
829
830/***************************************************************************
831 * Open an instance of the userdata module.
832 ***************************************************************************/
833BERR_Code BXVD_Userdata_Open(BXVD_ChannelHandle            hXvdCh,
834                             BXVD_Userdata_Handle         *phUserData,
835                             const BXVD_Userdata_Settings *pDefSettings)
836{
837   BERR_Code               eStatus = BERR_SUCCESS;
838   BXVD_P_UserDataContext *pUserdata = NULL;
839 
840   BDBG_ENTER(BXVD_Userdata_Open);
841               
842   BDBG_ASSERT(hXvdCh);
843   BDBG_ASSERT(phUserData);
844   BSTD_UNUSED(pDefSettings);
845 
846   /* Return null handle if we fail to create one */
847   *phUserData = NULL;
848 
849   /* Allocate user data handle */
850   pUserdata = (BXVD_P_UserDataContext*)(BKNI_Malloc(sizeof(BXVD_P_UserDataContext)));
851
852   if(!pUserdata)
853   {
854      return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
855   }
856   /* Clear out the context and set defaults. */
857   BKNI_Memset((void*)pUserdata, 0x0, sizeof(BXVD_P_UserDataContext));
858               
859   /* Set the handle type */
860   pUserdata->eHandleType = BXVD_P_HandleType_Userdata;
861
862   /* Take in default settings. */
863   pUserdata->sUserdataSettings = (pDefSettings) ? 
864      *pDefSettings : s_stUserdataDefaultSettings;
865
866   /* Initialize userdata parameters */
867   pUserdata->hXvdCh = hXvdCh;
868   pUserdata->bCallbackEnabled = false;
869   pUserdata->fUserdataCallback_isr = NULL;
870   pUserdata->errForwardError = BERR_SUCCESS;
871 
872   /* Allocate the userdata work buffer */
873   pUserdata->pBfr = BKNI_Malloc(pUserdata->sUserdataSettings.maxDataSize);
874   BDBG_ASSERT((uint32_t)pUserdata->pBfr%4==0);
875   if(!pUserdata->pBfr)
876   {
877      BKNI_Free(pUserdata);
878      return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
879   }
880 
881   /* All done. Return the new Channel context to user and set the global
882    * user data handle
883    */
884   *phUserData = hXvdCh->pUserData = (BXVD_Userdata_Handle)pUserdata;
885               
886   /* Initialize the userdata queue */
887   eStatus = BXVD_P_Userdata_QueueInitialize(&(hXvdCh->pUserData->queue), pUserdata->sUserdataSettings);
888
889#if BXVD_FLATTEN_USERDATA
890   BXVD_DBG_MSG(hXvdCh, ("Userdata will be delivered as coalesced packets"));
891#else
892   BXVD_DBG_MSG(hXvdCh, ("Userdata will be delivered as single packets"));
893#endif
894
895   BDBG_LEAVE(BXVD_Userdata_Open);
896   return eStatus;
897}
898
899/***************************************************************************
900* Close a previously opened userdata instance
901****************************************************************************/
902BERR_Code BXVD_Userdata_Close(BXVD_Userdata_Handle hUserData)
903{
904   BERR_Code eStatus = BERR_SUCCESS;
905
906   BDBG_ENTER(BXVD_Userdata_Close);
907   BDBG_ASSERT(hUserData);
908
909   /* Check handle type for correctness */
910   if (hUserData->eHandleType != BXVD_P_HandleType_Userdata)
911   {
912      BDBG_ERR(("Invalid handle type passed to function"));
913      return BERR_TRACE(BXVD_ERR_INVALID_HANDLE);
914   }
915
916   /* Clear internal state inside a critical section */
917   BKNI_EnterCriticalSection();
918   hUserData->bCallbackEnabled = false;
919   hUserData->fUserdataCallback_isr = NULL;
920   hUserData->hXvdCh->pUserData = NULL;
921   BKNI_LeaveCriticalSection();
922
923
924   BXVD_P_Userdata_QueueDestroy(&hUserData->queue,  hUserData->sUserdataSettings);
925
926   /*
927    * Release all allocated buffers
928    */
929   BKNI_Free(hUserData->pBfr);
930   BKNI_Free(hUserData);
931   hUserData = NULL;
932 
933   BDBG_LEAVE(BXVD_Userdata_Close);
934   return eStatus;
935}
936
937/***************************************************************************
938        * Read user data. Non-isr version
939****************************************************************************/
940BERR_Code BXVD_Userdata_Read(BXVD_Userdata_Handle   hUserData,
941                             BAVC_USERDATA_info    *pUserDataInfo)
942{
943   BERR_Code status;
944
945   /* Check handle type for correctness */
946   if (hUserData->eHandleType != BXVD_P_HandleType_Userdata)
947   {
948      BDBG_ERR(("Invalid handle type passed to function"));
949      return BERR_TRACE(BXVD_ERR_INVALID_HANDLE);
950   }
951
952   BKNI_EnterCriticalSection();
953   status = BXVD_Userdata_Read_isr(hUserData, pUserDataInfo);
954   BKNI_LeaveCriticalSection();
955   return status;
956}
957       
958
959/***************************************************************************
960        * Read user data. ISR version
961****************************************************************************/
962BERR_Code BXVD_Userdata_Read_isr(BXVD_Userdata_Handle   hUserData,
963                                 BAVC_USERDATA_info *pUserDataInfo)
964{
965   int protocol;
966   uint32_t uiDecodePictureId;
967   unsigned long ulFlags, ulPulldown, ulPTS;
968   BERR_Code       eStatus = BERR_SUCCESS;
969   size_t         offset;
970   uint8_t        *pDataBfr;
971   unsigned       entries;
972   unsigned long   ulUserDataAddr;
973#if BXVD_FLATTEN_USERDATA
974   bool            bMoreUserdata;
975#endif
976
977   UD_HDR *pHdr;
978
979   BDBG_ENTER(BXVD_Userdata_Read);
980   BDBG_ASSERT(hUserData);
981   BDBG_ASSERT(pUserDataInfo);
982   
983   protocol = 0;
984   ulUserDataAddr = 0;
985   uiDecodePictureId = 0;
986   ulFlags = ulPulldown = ulPTS = 0;
987
988   /* Check handle type for correctness */
989   if (hUserData->eHandleType != BXVD_P_HandleType_Userdata)
990   {
991      BDBG_ERR(("Invalid handle type passed to function"));
992      return BERR_TRACE(BXVD_ERR_INVALID_HANDLE);
993   }
994
995   /*
996    * Clear overflow flag. We'll set it if a queue full condition is
997    * detected below.
998    */
999   pUserDataInfo->bErrorBufferOverflow = false;
1000
1001   /*
1002    * If there was an error detected in the enqueuing routine.
1003    * forward it to the user callback unless it was a queue overflow
1004    */
1005   if (hUserData->errForwardError == BXVD_ERR_QUEUE_FULL)
1006   {
1007      BDBG_ERR(("Queue full condition detected, bErrorBufferOverflow set"));
1008      pUserDataInfo->bErrorBufferOverflow = true;     
1009   }
1010   else if (hUserData->errForwardError != BERR_SUCCESS)
1011   {
1012      BDBG_ERR(("Error detected in enqueuing routine"));
1013      return BERR_TRACE(hUserData->errForwardError);
1014   }
1015
1016   /* Clear out the user data info structure */
1017   BKNI_Memset((void *)pUserDataInfo, 0, sizeof(*pUserDataInfo));
1018
1019   /* Get the userdata from the queue */
1020   if (BXVD_P_Userdata_QueueRemove_isr(&(hUserData->queue), 
1021                                       &protocol, 
1022                                       &ulUserDataAddr,
1023                                       &ulFlags, 
1024                                       &ulPulldown,
1025                                       &ulPTS,
1026                                       &uiDecodePictureId,
1027                                       hUserData->sUserdataSettings)
1028       == BXVD_ERR_QUEUE_EMPTY)
1029   {
1030      return BXVD_ERR_USERDATA_NONE;
1031   }
1032
1033   /*
1034    * Overflow condition is checked by DM, so we can set overflow flag
1035    * to false here.
1036    */
1037   pUserDataInfo->bErrorBufferOverflow = false;
1038               
1039   /* Set field polarity flag */
1040   pUserDataInfo->bTopFieldFirst =
1041      (ulFlags & BXVD_P_PPB_FLAG_BOTTOM_FIRST) ? false : true;
1042               
1043   /* Set repeat flag */
1044   pUserDataInfo->bRepeatFirstField =
1045      ((ulPulldown == BXVD_P_PPB_PullDown_eTopBottomTop) ||
1046       (ulPulldown == BXVD_P_PPB_PullDown_eBottomTopBottom) ||
1047       (ulPulldown == BXVD_P_PPB_PullDown_eFrameX2) ||
1048       (ulPulldown == BXVD_P_PPB_PullDown_eFrameX3) ||
1049       (ulPulldown == BXVD_P_PPB_PullDown_eFrameX4)) ? true : false;
1050               
1051   /*
1052    * Copy the user data buffer pointer to the info structure and make a
1053    * local copy for processing
1054    */
1055   pUserDataInfo->pUserDataBuffer = hUserData->pBfr;
1056   pDataBfr = (uint8_t *)hUserData->pBfr;
1057
1058   /* Set up parsing loop initial conditions */
1059   offset = 0;
1060#if BXVD_FLATTEN_USERDATA
1061   bMoreUserdata = true;
1062   /* Parse and format the user data */
1063   while( bMoreUserdata )
1064   {
1065#endif
1066      /* Pass on the PTS and PTS valid   flag */
1067      pUserDataInfo->ui32PTS = ulPTS;
1068      pUserDataInfo->bPTSValid = (ulFlags&BXVD_P_PPB_FLAG_PTS_PRESENT)?true : false;
1069
1070      /* Pass on the decode picture id */
1071      pUserDataInfo->ulDecodePictureId = uiDecodePictureId;
1072
1073      /* Get Userdata info */
1074      pHdr = (UD_HDR *)ulUserDataAddr;
1075
1076      /*
1077       * Parse the user data.
1078       */
1079      /* Valid for mpeg2 only */
1080      if (pHdr->type & BXVD_P_PPB_MPEG_USERDATA_TYPE_I)
1081         pUserDataInfo->ePicCodingType = BAVC_USERDATA_PictureCoding_eI;
1082      else if (pHdr->type & BXVD_P_PPB_MPEG_USERDATA_TYPE_P)
1083         pUserDataInfo->ePicCodingType = BAVC_USERDATA_PictureCoding_eP;
1084      else
1085         pUserDataInfo->ePicCodingType = BAVC_USERDATA_PictureCoding_eB;
1086                                       
1087      /* Get userdata type */
1088      if (BXVD_IS_AVC(protocol))
1089      {
1090         pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eSEI;
1091      }
1092      else if (BXVD_IS_MPEG(protocol))
1093      {
1094         if (pHdr->type & BXVD_P_PPB_MPEG_USERDATA_TYPE_SEQ)
1095            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eSeq;
1096         else if (pHdr->type & BXVD_P_PPB_MPEG_USERDATA_TYPE_GOP)
1097            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eGOP;
1098         else
1099            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_ePicture;
1100      }
1101      else if (BXVD_IS_AVS(protocol))
1102      {
1103         pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eFrame;
1104      }
1105      else   /* VC1 */
1106      {
1107         if (pHdr->type & BXVD_P_PPB_VC1_USERDATA_TYPE_SEQ)
1108            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eSeq;
1109         else if (pHdr->type & BXVD_P_PPB_VC1_USERDATA_TYPE_ENTRYPOINT)
1110            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eEntryPoint;
1111         else if (pHdr->type & BXVD_P_PPB_VC1_USERDATA_TYPE_FLD)
1112            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eField;
1113         else if (pHdr->type & BXVD_P_PPB_VC1_USERDATA_TYPE_FRM)
1114            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eFrame;
1115         else
1116            pUserDataInfo->eUserDataType = BAVC_USERDATA_Type_eSlice;
1117      }
1118                                       
1119      /* mpeg2 and avc uses the same it fields defs */
1120      if (pHdr->type & BXVD_P_PPB_MPEG_USERDATA_TYPE_TOP)
1121         pUserDataInfo->eSourcePolarity = BAVC_Polarity_eTopField;
1122      else if (pHdr->type & BXVD_P_PPB_MPEG_USERDATA_TYPE_BOT)
1123         pUserDataInfo->eSourcePolarity = BAVC_Polarity_eBotField;
1124      else
1125         pUserDataInfo->eSourcePolarity = BAVC_Polarity_eFrame;
1126                                       
1127      /* Check the user data packet size */
1128      if(offset+4 > (size_t)hUserData->sUserdataSettings.maxDataSize)
1129      {
1130         BDBG_WRN(("user data packet is too big %u+%u(%u)[%u]", 
1131                   offset, 
1132                   4, 
1133                   offset+4, 
1134                   hUserData->sUserdataSettings.maxDataSize));
1135                                                       
1136         eStatus = BERR_TRACE(BXVD_ERR_USERDATA_USRBFROFL);
1137         goto consume;
1138      }
1139                                       
1140      /* Check buffer alignment */
1141      if ((uint32_t)pDataBfr % 4)
1142      {
1143         BDBG_WRN(("user data buffer is unaligned"));
1144         eStatus = BERR_TRACE(BXVD_ERR_USERDATA_INVALID);
1145         goto consume;
1146                                                       
1147      }
1148                                       
1149      /* Create simulated data headers based on protocol */
1150      if (BXVD_IS_AVC(protocol))
1151      {
1152         /*     simulate NAL and SEI header */
1153         pDataBfr[offset++] = 0x00;
1154         pDataBfr[offset++] = 0x00;
1155         pDataBfr[offset++] = 0x00;
1156         pDataBfr[offset++] = 0x00;
1157                                                       
1158         pDataBfr[offset++] = 0x01;
1159         pDataBfr[offset++] = 0x06;
1160
1161         if (pHdr->type == BXVD_P_PPB_H264_USERDATA_TYPE_REGISTERED)
1162         {
1163            pDataBfr[offset++] = (uint8_t) BXVD_USERDATA_H264_TYPE_REGISTERED;
1164         }
1165         else if (pHdr->type == BXVD_P_PPB_H264_USERDATA_TYPE_FRAME_PACK)
1166         {
1167            pDataBfr[offset++] = (uint8_t) BXVD_USERDATA_H264_TYPE_FRAME_PACK;
1168         }
1169         else
1170         {
1171            pDataBfr[offset++] = (uint8_t) BXVD_USERDATA_H264_TYPE_UNREGISTERED;
1172         }
1173
1174         pDataBfr[offset++] = (uint8_t)pHdr->size;
1175      } 
1176      else if (protocol == BAVC_VideoCompressionStd_eVC1)
1177      {
1178         pDataBfr[offset++] = 0x00;
1179         pDataBfr[offset++] = 0x00;
1180         pDataBfr[offset++] = 0x01;
1181         pDataBfr[offset++] = 0x1E;
1182      }
1183      else 
1184      {
1185         /* <MPEG-2> An extra 0 is prepended to keep data aligned to 32 bits */
1186         pDataBfr[offset++] = 0x00;
1187         pDataBfr[offset++] = 0x00;
1188         pDataBfr[offset++] = 0x00;
1189         pDataBfr[offset++] = 0x01;
1190      }
1191                                       
1192      /* Check the user data packet size again after header creation */
1193      if(offset+pHdr->size >
1194         (size_t)hUserData->sUserdataSettings.maxDataSize)
1195      {
1196         BDBG_WRN(("user data packet is too big %u+%u(%u)[%u]",
1197                   offset, 
1198                   pHdr->size, 
1199                   offset+pHdr->size, 
1200                   hUserData->sUserdataSettings.maxDataSize));
1201                                                       
1202         eStatus = BERR_TRACE(BXVD_ERR_USERDATA_USRBFROFL);
1203         goto consume;
1204      }
1205                                       
1206      /* Get number of 32 bit entries */
1207      entries = (pHdr->size+3)>>2; 
1208                                       
1209      /* Copy segment of user data after verifying source and destination pointers */
1210      if (&(pDataBfr[offset]) == NULL || (void *)(ulUserDataAddr + sizeof(BXVD_P_UserData)) == NULL)
1211      {
1212         BDBG_WRN(("Attempt to dereference a NULL user data buffer", NULL));
1213         eStatus = BERR_TRACE(BXVD_ERR_USERDATA_INVALID);
1214         goto consume;
1215      }
1216      BKNI_Memcpy((void *)&(pDataBfr[offset]),
1217                  (void *)(ulUserDataAddr + sizeof(BXVD_P_UserData)),
1218                  entries*4);
1219
1220#if BSTD_CPU_ENDIAN == BSTD_ENDIAN_LITTLE
1221      { /* convert endianess */
1222         uint32_t data;
1223         unsigned i;
1224         for(i=0;i<entries;i++) 
1225         {
1226            data = ((uint32_t *)(pDataBfr+offset))[i];
1227            data = ((data >> 24) & 0xFF) |
1228               ((data >> 8) & 0xFF00) |
1229               ((data & 0xFF00) << 8) |
1230               ((data & 0xFF) << 24);
1231            ((uint32_t *)(pDataBfr+offset))[i] = data;
1232         }
1233      }
1234#elif   BSTD_CPU_ENDIAN == BSTD_ENDIAN_BIG
1235/* do nothing */
1236#else   
1237#error   "Not supported"
1238#endif
1239
1240      /* Adjust packet size */
1241      offset += pHdr->size;
1242                                       
1243      /* Align to 32 bits and pad with 0 */
1244      switch(offset%4)
1245      {
1246         case 1:
1247            pDataBfr[offset++] = 0x00;
1248            /* Fallthrough */
1249         case 2:
1250            pDataBfr[offset++] = 0x00;
1251            /* Fallthrough */
1252         case 3:
1253            pDataBfr[offset++] = 0x00;
1254            /* Fallthrough */
1255         default:
1256            break;
1257      }
1258#if BXVD_FLATTEN_USERDATA
1259      /* Get the userdata from the queue */
1260      if (BXVD_P_Userdata_QueueRemove_isr(&(hUserData->queue), 
1261                                          &protocol, 
1262                                          &ulUserDataAddr,
1263                                          &ulFlags, 
1264                                          &ulPulldown,
1265                                          &ulPTS,
1266                                          &uiDecodePictureId,
1267                                          hUserData->sUserdataSettings)
1268          == BXVD_ERR_QUEUE_EMPTY)
1269      {
1270         bMoreUserdata = false;
1271      }
1272#if BXVD_BREAK_ON_TYPE_CHANGE
1273      else
1274      {
1275         UD_HDR *tmp;
1276         tmp = (UD_HDR *)ulUserDataAddr;
1277         if (tmp->type != pHdr->type)
1278         {
1279            BDBG_MSG(("tmp->type : pHdr->type", tmp->type, pHdr->type));
1280            break;
1281         }
1282      }
1283#endif
1284   }
1285#endif
1286   /* Set the new packet size in user data info struct */
1287   pUserDataInfo->ui32UserDataBufSize = offset;
1288
1289#if BXVD_USERDATA_EXTRA_DEBUG
1290   {
1291      uint32_t x;
1292      BXVD_PTSInfo ptsInfo;
1293      BKNI_Printf("ui32UserDataBufSize = 0x%x (%d)\n", offset, offset);
1294      BKNI_Printf("pHdr->type = 0x%x (%d)\n", pHdr->type, pHdr->type);
1295      if (ulPTS == 0)
1296      {
1297         BXVD_GetPTS_isr(hUserData->hXvdCh, &ptsInfo);
1298         BKNI_Printf("Interpolated running PTS = 0x%x (%u) - ", 
1299                     ptsInfo.ui32RunningPTS,
1300                     ptsInfo.ui32RunningPTS);
1301         BKNI_Printf("Interpolated effective PTS = 0x%x (%u)\n", 
1302                     ptsInfo.ui32EffectivePTS,
1303                     ptsInfo.ui32EffectivePTS);
1304
1305      }
1306      else
1307         BKNI_Printf("PTS = 0x%x (%d)\n", ulPTS, ulPTS);
1308      BKNI_Printf("pUserDataInfo->eUserDataType = 0x%x (%d)\n", 
1309                  pUserDataInfo->eUserDataType, 
1310                  pUserDataInfo->eUserDataType);
1311      for (x = 0; x < offset; x++)
1312      {
1313         if (!((x+1)%45))
1314            BKNI_Printf("<end>\n");
1315         BKNI_Printf("%2.2x ", pDataBfr[x]);
1316      }
1317      BKNI_Printf("<end>\n");
1318      BKNI_Printf("actual size: 0x%x (%d)\n", x, x);
1319      BKNI_Printf("------------------------------------------------------\n"); 
1320   }
1321#endif
1322
1323  consume:
1324                       
1325   BDBG_LEAVE(BXVD_Userdata_Read);
1326   return eStatus;
1327}
1328
1329/***************************************************************************
1330 * Install the userdata read interrupt callback
1331 ***************************************************************************/
1332BERR_Code BXVD_Userdata_InstallInterruptCallback
1333(
1334   BXVD_Userdata_Handle    hUserData,
1335   BINT_CallbackFunc       xvdInterruptCallBack,
1336   void                   *pParm1,
1337   int                     parm2
1338   )
1339{
1340   BDBG_ENTER(BXVD_Userdata_InstallInterruptCallback);
1341 
1342   BDBG_ASSERT(hUserData);
1343   BDBG_ASSERT(xvdInterruptCallBack);
1344   BSTD_UNUSED(parm2);
1345
1346   /* Check handle type for correctness */
1347   if (hUserData->eHandleType != BXVD_P_HandleType_Userdata)
1348   {
1349      BDBG_ERR(("Invalid handle type passed to function"));
1350      return BERR_TRACE(BXVD_ERR_INVALID_HANDLE);
1351   }
1352
1353   hUserData->fUserdataCallback_isr = xvdInterruptCallBack;
1354   hUserData->pParm1 = pParm1;
1355   hUserData->parm2  = parm2;
1356 
1357   hUserData->bCallbackEnabled = false;
1358               
1359   BDBG_LEAVE(BXVD_Userdata_InstallInterruptCallback);
1360   return BERR_SUCCESS;
1361}
1362
1363/***************************************************************************
1364 * Uninstall the read interrupt callback
1365 ***************************************************************************/
1366BERR_Code BXVD_Userdata_UninstallInterruptCallback
1367(
1368   BXVD_Userdata_Handle    hUserData,
1369   BINT_CallbackFunc       xvdInterruptCallBack
1370   )
1371{
1372   BDBG_ENTER(BXVD_Userdata_UninstallInterruptCallback);
1373               
1374   BDBG_ASSERT(hUserData);
1375   BSTD_UNUSED(xvdInterruptCallBack);
1376
1377   /* Check handle type for correctness */
1378   if (hUserData->eHandleType != BXVD_P_HandleType_Userdata)
1379   {
1380      BDBG_ERR(("Invalid handle type passed to function"));
1381      return BERR_TRACE(BXVD_ERR_INVALID_HANDLE);
1382   }
1383
1384   hUserData->bCallbackEnabled = false;
1385               
1386   hUserData->fUserdataCallback_isr = NULL;
1387   hUserData->pParm1 = 0;
1388   hUserData->parm2  = 0;
1389 
1390   BDBG_LEAVE(BXVD_Userdata_UninstallInterruptCallback);
1391   return BERR_SUCCESS;
1392}
1393
1394/***************************************************************************
1395 * Enable userdata
1396 ***************************************************************************/
1397BERR_Code BXVD_Userdata_Enable
1398(
1399   BXVD_Userdata_Handle     hUserData,
1400   bool                     bEnable
1401   )
1402{
1403   BDBG_ENTER(BXVD_Userdata_Enable);
1404   BDBG_ASSERT(hUserData);
1405               
1406   /* Check handle type for correctness */
1407   if (hUserData->eHandleType != BXVD_P_HandleType_Userdata)
1408   {
1409      BDBG_ERR(("Invalid handle type passed to function"));
1410      return BERR_TRACE(BXVD_ERR_INVALID_HANDLE);
1411   }
1412
1413   hUserData->bCallbackEnabled = bEnable;
1414
1415   /* If user data is being enabled, clear the existing queue */
1416   if (bEnable == true)
1417   {
1418      BXVD_P_Userdata_QueueClear(&(hUserData->queue), hUserData->sUserdataSettings);
1419   }
1420               
1421   BDBG_LEAVE(BXVD_Userdata_Enable);
1422   return BERR_SUCCESS;
1423}
1424/* End of File */
Note: See TracBrowser for help on using the repository browser.