DVBCore  20.3.0
DVBCore Documentation
stbresmgr.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2007 Ocean Blue Software Ltd
4  *
5  * This file is part of a DTVKit Software Component
6  * You are permitted to copy, modify or distribute this file subject to the terms
7  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
8  *
9  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
10  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
11  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * If you or your organisation is not a member of DTVKit then you have access
14  * to this source code outside of the terms of the licence agreement
15  * and you are expected to delete this and any associated files immediately.
16  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
17  *******************************************************************************/
25 /*---includes for this file--------------------------------------------------*/
26 /* compiler library header files */
27 #include <string.h>
28 
29 /* third party header files */
30 
31 /* DVBCore header files */
32 
33 #include <techtype.h>
34 #include <dbgfuncs.h>
35 
36 #include "stbdpc.h"
37 #include "stbresmgr.h"
38 #include "stbsitab.h"
39 #include "stbheap.h"
40 #include "stbhwtun.h"
41 #include "stbhwdmx.h"
42 
43 #ifdef COMMON_INTERFACE
44 #include "stbhwci.h"
45 #include "stbcicc.h"
46 #endif
47 
48 
49 /*---constant definitions for this file--------------------------------------*/
50 /*#define STB_RES_DEBUG*/
51 
52 #ifdef STB_RES_DEBUG
53 #define STB_RES_DBG(x) STB_SPDebugWrite x
54 #else
55 #define STB_RES_DBG(x)
56 #endif
57 
58 /*---local typedef structs for this file---------------------------------------*/
59 
60 typedef struct
61 {
62  BOOLEAN disabled;
63  U8BIT usage_count; /* Number of times the tuner has been acquired */
64  U8BIT high_count; /* Number of times the tuner has been acquired with a high priority */
65  U16BIT tuner_type; /* Type of tuner (terrestrial / cable / etc) */
66  void *tuned_transport; /* Transport that this tuner is tuned to */
67  E_STB_DP_RES_OWNER owner; /* Owner of the resource */
69 
70 typedef struct
71 {
72  U8BIT usage_count; /* Number of times the demux has been acquired */
73  U16BIT caps; /* Demux capability flags */
75 
76 typedef struct
77 {
78  BOOLEAN is_acquired; /* TRUE if the decoder has been acquired */
80 
81 typedef struct
82 {
83  U8BIT usage_count; /* Number of times the slot has been acquired */
84  void *service; /* Service this CI slot is associated with */
86 
87 
88 /*---local (static) variable declarations for this file----------------------*/
89 /* (internal variables declared static to make them local) */
90 
91 static BOOLEAN res_initialised = FALSE;
92 
93 static U8BIT num_tuners; /* Number of tuners in the system */
94 static S_TUNER_STATUS *tuner_status; /* Status of each tuner in the system */
95 static U8BIT num_demuxes; /* Number of demux paths */
96 static S_DEMUX_STATUS *demux_status; /* Status of each demux path */
97 static U8BIT num_audio_decoders; /* Number of audio decoders in the system */
98 static S_DECODER_STATUS *audio_decoder_status; /* Status of each audio decoder in the system */
99 static S_DECODER_STATUS *ad_decoder_status; /* Status of each AD decoder in the system */
100 static U8BIT num_video_decoders; /* Number of decoders in the system */
101 static S_DECODER_STATUS *video_decoder_status; /* Status of each video decoder in the system */
102 static U8BIT num_ci_slots; /* Number of CI slots in the system */
103 static S_CI_SLOT_STATUS *ci_slot_status; /* Status of each CI slot in the system */
104 
105 
106 /*---local function prototypes for this file---------------------------------*/
107 /* (internal functions declared static to make them local) */
108 
109 
110 /*---global function definitions---------------------------------------------*/
111 
112 /*!**************************************************************************
113  * @brief Creates and initialises control structures for the resources to be managed
114  * @param None
115  * @return TRUE if successful
116  ****************************************************************************/
117 BOOLEAN STB_RESInitialise(void)
118 {
119  U8BIT i;
120  S_TUNER_STATUS *tuner;
121  S_DECODER_STATUS *decoder;
122  S_DEMUX_STATUS *demux;
123  E_STB_TUNE_SIGNAL_TYPE signal_type;
124 #ifdef COMMON_INTERFACE
125  S_CI_SLOT_STATUS *slot;
126 #endif
127 
128  FUNCTION_START(STB_RESInitialise);
129 
130  if (!res_initialised)
131  {
132  /* Initialise the tuner management */
133  num_tuners = STB_HWGetTunerPaths();
134  if (num_tuners > 0)
135  {
136  tuner_status = (S_TUNER_STATUS *)STB_GetMemory((U32BIT)(sizeof(S_TUNER_STATUS) * num_tuners));
137  if (tuner_status != NULL)
138  {
139  STB_RES_DBG(("STB_RESInitialise: Initialising %d tuners", num_tuners));
140  for (i = 0, tuner = &tuner_status[0]; i < num_tuners; tuner++, i++)
141  {
142  memset(tuner, 0, sizeof(*tuner));
143 
144  tuner->tuner_type = SIGNAL_NONE;
145 
146  signal_type = STB_TuneGetSignalType(i);
147 
148  if ((signal_type & TUNE_SIGNAL_ANALOG) != 0)
149  {
150  tuner->tuner_type |= SIGNAL_ANALOG;
151  }
152  if ((signal_type & TUNE_SIGNAL_COFDM) != 0)
153  {
154  tuner->tuner_type |= SIGNAL_COFDM;
155  }
156  if ((signal_type & TUNE_SIGNAL_QAM) != 0)
157  {
158  tuner->tuner_type |= SIGNAL_QAM;
159  }
160  if ((signal_type & TUNE_SIGNAL_QPSK) != 0)
161  {
162  tuner->tuner_type |= SIGNAL_QPSK;
163  }
164 
165  tuner->disabled = FALSE;
166  tuner->tuned_transport = NULL;
167  tuner->owner = RES_OWNER_NONE;
168  }
169  }
170  }
171  else
172  {
173  STB_RES_DBG(("STB_RESInitialise: No tuners!"));
174  tuner_status = NULL;
175  }
176 
177  num_demuxes = STB_HWGetDemuxPaths();
178  if (num_demuxes > 0)
179  {
180  demux_status = (S_DEMUX_STATUS *)STB_GetMemory((U32BIT)(sizeof(S_DEMUX_STATUS) * num_demuxes));
181  if (demux_status != NULL)
182  {
183  STB_RES_DBG(("STB_RESInitialise: Initialising %d demuxes", num_demuxes));
184  for (i = 0, demux = &demux_status[0]; i < num_demuxes; demux++, i++)
185  {
186  memset(demux, 0, sizeof(*demux));
187 
188  demux->caps = STB_DMXGetCapabilities(i);
189  }
190  }
191  }
192  else
193  {
194  STB_RES_DBG(("STB_RESInitialise: No demuxes!"));
195  demux_status = NULL;
196  }
197 
198  num_audio_decoders = STB_HWGetAudioDecodePaths();
199  if (num_audio_decoders > 0)
200  {
201  audio_decoder_status = (S_DECODER_STATUS *)STB_GetMemory((U32BIT)(sizeof(S_DECODER_STATUS) * num_audio_decoders));
202  if (audio_decoder_status != NULL)
203  {
204  STB_RES_DBG(("STB_RESInitialise: Initialising %d audio decoders", num_audio_decoders));
205  for (i = 0, decoder = &audio_decoder_status[0]; i < num_audio_decoders; decoder++, i++)
206  {
207  decoder->is_acquired = FALSE;
208  }
209  }
210  ad_decoder_status = (S_DECODER_STATUS *)STB_GetMemory((U32BIT)(sizeof(S_DECODER_STATUS) * num_audio_decoders));
211  if (ad_decoder_status != NULL)
212  {
213  STB_RES_DBG(("STB_RESInitialise: Initialising %d AD decoders", num_audio_decoders));
214  for (i = 0, decoder = &ad_decoder_status[0]; i < num_audio_decoders; decoder++, i++)
215  {
216  decoder->is_acquired = FALSE;
217  }
218  }
219  }
220  else
221  {
222  STB_RES_DBG(("STB_RESInitialise: No audio decoders!"));
223  audio_decoder_status = NULL;
224  ad_decoder_status = NULL;
225  }
226 
227  num_video_decoders = STB_HWGetVideoDecodePaths();
228  if (num_video_decoders > 0)
229  {
230  video_decoder_status = (S_DECODER_STATUS *)STB_GetMemory((U32BIT)(sizeof(S_DECODER_STATUS) * num_video_decoders));
231  if (video_decoder_status != NULL)
232  {
233  STB_RES_DBG(("STB_RESInitialise: Initialising %d video decoders", num_video_decoders));
234  for (i = 0, decoder = &video_decoder_status[0]; i < num_video_decoders; decoder++, i++)
235  {
236  decoder->is_acquired = FALSE;
237  }
238  }
239  }
240  else
241  {
242  STB_RES_DBG(("STB_RESInitialise: No video decoders!"));
243  video_decoder_status = NULL;
244  }
245 
246 #ifdef COMMON_INTERFACE
247  num_ci_slots = STB_CIGetSlotCount();
248  if (num_ci_slots > 0)
249  {
250  ci_slot_status = (S_CI_SLOT_STATUS *)STB_GetMemory((U32BIT)(sizeof(S_CI_SLOT_STATUS) * num_ci_slots));
251  if (ci_slot_status != NULL)
252  {
253  STB_RES_DBG(("STB_RESInitialise: Initialising %d CI slots", num_ci_slots));
254  for (i = 0, slot = &ci_slot_status[0]; i < num_ci_slots; slot++, i++)
255  {
256  slot->usage_count = 0;
257  slot->service = NULL;
258  }
259  }
260  }
261  else
262  {
263  ci_slot_status = NULL;
264  }
265 #endif
266 
267  res_initialised = TRUE;
268  }
269 
270  FUNCTION_FINISH(STB_RESInitialise);
271 
272  return(res_initialised);
273 }
274 
275 /*!**************************************************************************
276  * @brief Returns the number of tuners
277  * @return Number of tuners on the system
278  ****************************************************************************/
279 U8BIT STB_RESNumTuners(void)
280 {
281  FUNCTION_START(STB_RESNumTuners);
282  FUNCTION_FINISH(STB_RESNumTuners);
283  return(num_tuners);
284 }
285 
286 /*!**************************************************************************
287  * @brief Acquires a tuner. Tuners will be reused if possible
288  * @param tuner_type - type of tuner to be acquired
289  * @param transport - initial transport the tuner will be tuned to
290  * @param owner - module acquiring the tuner
291  * @param high_priority - TRUE if the request is a high priority, meaning a tuner acquired with
292  * a lower priority can be taken. A tuner acquired with a high priority
293  * will be locked, preventing it being retuned.
294  * @param tuner_taken - returned as TRUE if the acquired tuner was in use but is reacquired.
295  * @return The ID of the tuner acquired or INVALID_RES_ID if none are available
296  ****************************************************************************/
297 U8BIT STB_RESAcquireTuner(E_STB_DP_SIGNAL_TYPE tuner_type, void *transport, E_STB_DP_RES_OWNER owner,
298  BOOLEAN high_priority, BOOLEAN *tuner_taken)
299 {
300  U8BIT i;
301  U8BIT tuner_id = INVALID_RES_ID;
302 
303  FUNCTION_START(STB_RESAcquireTuner);
304 
305  *tuner_taken = FALSE;
306 
307  if (res_initialised)
308  {
309  if (transport != NULL)
310  {
311  /* See if a tuner is currently tuned to this transport and the owner is the same */
312  for (i = 0; (i < num_tuners) && (tuner_id == INVALID_RES_ID); i++)
313  {
314  if ((tuner_status[i].tuned_transport == transport))
315  {
316  tuner_status[i].usage_count++;
317 
318  if ((tuner_status[i].owner == RES_OWNER_NONE) && (owner != RES_OWNER_NONE))
319  {
320  /* Tuner is now owned by a module */
321  tuner_status[i].owner = owner;
322  }
323 
324  if (high_priority)
325  {
326  /* This tuner can't be tuned to another transport until it's released */
327  tuner_status[i].high_count++;
328  }
329 
330  tuner_id = i;
331  }
332  }
333  }
334 
335  if ((tuner_id == INVALID_RES_ID) || (transport == NULL))
336  {
337  /* Look for a tuner of the given type that hasn't been acquired yet */
338  for (i = 0; (i < num_tuners) && (tuner_id == INVALID_RES_ID); i++)
339  {
340  if (!tuner_status[i].disabled && (tuner_status[i].usage_count == 0) &&
341  ((tuner_status[i].tuner_type & tuner_type) != 0))
342  {
343  if (high_priority)
344  {
345  tuner_status[i].high_count++;
346  }
347 
348  tuner_status[i].usage_count++;
349  tuner_status[i].owner = owner;
350  tuner_id = i;
351 
352  STB_TuneSetSignalType(tuner_id, tuner_type);
353  }
354  }
355 
356  if ((tuner_id == INVALID_RES_ID) && high_priority)
357  {
358  /* All tuners are being used but this request has a higher priority so find one that
359  * isn't currently being used with a high priority and isn't owned by another module */
360  for (i = 0; (i < num_tuners) && (tuner_id == INVALID_RES_ID); i++)
361  {
362  if (!tuner_status[i].disabled && ((tuner_status[i].tuner_type & tuner_type) != 0) &&
363  (tuner_status[i].high_count == 0) && (tuner_status[i].owner == RES_OWNER_NONE))
364  {
365  tuner_status[i].tuned_transport = transport;
366  tuner_status[i].high_count++;
367  tuner_status[i].usage_count++;
368  tuner_status[i].owner = owner;
369  tuner_id = i;
370  *tuner_taken = TRUE;
371 
372  STB_TuneSetSignalType(tuner_id, tuner_type);
373  }
374  }
375  }
376  }
377  }
378 
379 #ifdef STB_RES_DEBUG
380  if (tuner_id == INVALID_RES_ID)
381  {
382  STB_RES_DBG(("STB_RESAcquireTuner(%u, %p, %u): Failed to acquire a tuner for owner %u", tuner_type,
383  transport, high_priority, owner));
384  }
385  else
386  {
387  STB_RES_DBG(("STB_RESAcquireTuner(%u, %p, %u): Tuner %u acquired, usage_count=%u, high_count=%u, owner=%u",
388  tuner_type, transport, high_priority, tuner_id, tuner_status[tuner_id].usage_count,
389  tuner_status[tuner_id].high_count, owner));
390  }
391 #endif
392 
393  FUNCTION_FINISH(STB_RESAcquireTuner);
394 
395  return(tuner_id);
396 }
397 
398 /*!**************************************************************************
399  * @brief Releases a tuner that has previously been acquired
400  * @param tuner_id - ID of a tuner previously acquired
401  * @param high_priority - TRUE if the tuner was acquired with a high priority
402  * @param owner - module releasing the tuner
403  ****************************************************************************/
404 void STB_RESReleaseTuner(U8BIT tuner_id, BOOLEAN high_priority, E_STB_DP_RES_OWNER owner)
405 {
406  FUNCTION_START(STB_RESReleaseTuner);
407 
408  if (res_initialised)
409  {
410  ASSERT(tuner_id < num_tuners);
411 
412  if (tuner_id < num_tuners)
413  {
414  STB_RES_DBG(("STB_RESReleaseTuner(%u, %u, %u): usage_count=%u, high_count=%u, owner=%u",
415  tuner_id, high_priority, owner, tuner_status[tuner_id].usage_count,
416  tuner_status[tuner_id].high_count, tuner_status[tuner_id].owner));
417 
418  if (high_priority)
419  {
420  tuner_status[tuner_id].high_count--;
421  }
422 
423  if (tuner_status[tuner_id].usage_count != 0)
424  {
425  tuner_status[tuner_id].usage_count--;
426  if (tuner_status[tuner_id].usage_count == 0)
427  {
428  /* Tuner is no longer in use */
429  tuner_status[tuner_id].tuned_transport = NULL;
430  tuner_status[tuner_id].owner = RES_OWNER_NONE;
431 
432  STB_TuneSetSignalType(tuner_id, TUNE_SIGNAL_NONE);
433  }
434  else if (tuner_status[tuner_id].owner == owner)
435  {
436  tuner_status[tuner_id].owner = RES_OWNER_NONE;
437  }
438  }
439 #ifdef STB_RES_DEBUG
440  else
441  {
442  STB_RES_DBG(("STB_RESReleaseTuner(%u): Tuner released too many times!", tuner_id));
443  }
444 #endif
445  }
446  }
447 
448  FUNCTION_FINISH(STB_RESReleaseTuner);
449 }
450 
457 void STB_RESSetTunerDisabled(U8BIT tuner_id, BOOLEAN disable)
458 {
459  FUNCTION_START(STB_RESSetTunerDisabled);
460 
461  if (res_initialised)
462  {
463  ASSERT(tuner_id < num_tuners);
464 
465  if (tuner_id < num_tuners)
466  {
467  tuner_status[tuner_id].disabled = disable;
468  }
469  }
470 
471  FUNCTION_FINISH(STB_RESSetTunerDisabled);
472 }
473 
479 BOOLEAN STB_RESIsTunerDisabled(U8BIT tuner_id)
480 {
481  BOOLEAN disabled;
482 
483  FUNCTION_START(STB_RESIsTunerDisabled);
484 
485  disabled = TRUE;
486 
487  if (res_initialised)
488  {
489  ASSERT(tuner_id < num_tuners);
490 
491  if (tuner_id < num_tuners)
492  {
493  disabled = tuner_status[tuner_id].disabled;
494  }
495  }
496 
497  FUNCTION_FINISH(STB_RESIsTunerDisabled);
498 
499  return(disabled);
500 }
501 
507 {
508  U8BIT id, enabled_tuners;
509 
510  FUNCTION_START(STB_RESNumEnabledTuners);
511 
512  enabled_tuners = 0;
513 
514  for (id = 0; id < num_tuners; id++)
515  {
516  if (!tuner_status[id].disabled)
517  {
518  enabled_tuners++;
519  }
520  }
521 
522  FUNCTION_FINISH(STB_RESNumEnabledTuners);
523 
524  return(enabled_tuners);
525 }
526 
527 /*!**************************************************************************
528  * @brief Sets the owner of the tuner
529  * @param tuner_id - ID of a tuner
530  * @param owner - module acquiring the tuner
531  ****************************************************************************/
532 void STB_RESSetTunerOwner(U8BIT tuner_id, E_STB_DP_RES_OWNER owner)
533 {
534  FUNCTION_START(STB_RESSetTunerOwner);
535 
536  if (res_initialised)
537  {
538  ASSERT(tuner_id < num_tuners);
539 
540  if (tuner_id < num_tuners)
541  {
542  tuner_status[tuner_id].owner = owner;
543  }
544  }
545 
546  FUNCTION_FINISH(STB_RESSetTunerOwner);
547 }
548 
549 /*!**************************************************************************
550  * @brief Returns the type of the given tuner
551  * @param tuner_id - ID of a tuner
552  * @return tuner type, SIGNAL_NONE on error
553  ****************************************************************************/
554 E_STB_DP_SIGNAL_TYPE STB_RESGetTunerType(U8BIT tuner_id)
555 {
556  E_STB_DP_SIGNAL_TYPE type;
557 
558  FUNCTION_START(STB_RESGetTunerType);
559 
560  type = SIGNAL_NONE;
561 
562  if (res_initialised)
563  {
564  ASSERT(tuner_id < num_tuners);
565 
566  if (tuner_id < num_tuners)
567  {
568  type = tuner_status[tuner_id].tuner_type;
569  }
570  }
571 
572  FUNCTION_FINISH(STB_RESGetTunerType);
573 
574  return(type);
575 }
576 
577 /*!**************************************************************************
578  * @brief Saves the transport pointer with the specified tuner
579  * @param tuner_id - ID of a previously acquired tuner
580  * @param t_ptr - pointer to the transport record to be saved
581  * @return None
582  ****************************************************************************/
583 void STB_RESSetTunedTransport(U8BIT tuner_id, void *t_ptr)
584 {
585  FUNCTION_START(STB_RESSetTunedTransport);
586 
587  if (res_initialised)
588  {
589  ASSERT(tuner_id < num_tuners);
590 
591  /* Only set the transport if the tuner isn't being used by more than one decode path */
592  if ((tuner_id < num_tuners) && (tuner_status[tuner_id].usage_count == 1))
593  {
594  tuner_status[tuner_id].tuned_transport = t_ptr;
595  }
596  }
597 
598  FUNCTION_FINISH(STB_RESSetTunedTransport);
599 }
600 
601 /*!**************************************************************************
602  * @brief Returns the transport record saved with the specified tuner
603  * @param tuner_id - ID of a tuner
604  * @return Pointer to the transport record saved with the tuner
605  ****************************************************************************/
606 void* STB_RESGetTunedTransport(U8BIT tuner_id)
607 {
608  void *t_ptr = NULL;
609 
610  FUNCTION_START(STB_RESGetTunedTransport);
611 
612  if (res_initialised)
613  {
614  ASSERT(tuner_id < num_tuners);
615 
616  if (tuner_id < num_tuners)
617  {
618  t_ptr = tuner_status[tuner_id].tuned_transport;
619  }
620  }
621 
622  FUNCTION_FINISH(STB_RESGetTunedTransport);
623 
624  return(t_ptr);
625 }
626 
627 /*!**************************************************************************
628  * @brief Returns whether there's a tuner available to tune to the given transport
629  * @param tuner_type - tuner type
630  * @param transport - transport to be tuned to
631  * @return TRUE if a tuner is available, FALSE otherwise
632  ****************************************************************************/
633 BOOLEAN STB_RESCanTuneToTransport(E_STB_DP_SIGNAL_TYPE tuner_type, void *transport)
634 {
635  U8BIT i;
636  BOOLEAN can_tune;
637 
638  FUNCTION_START(STB_RESCanTuneToTransport);
639 
640  can_tune = FALSE;
641 
642  /* See if there's a tuner already tuned to this transport or one of the right type that can be tuned */
643  for (i = 0; (i < num_tuners) && !can_tune; i++)
644  {
645  if (((tuner_status[i].usage_count > 0) && (tuner_status[i].tuned_transport == transport)) ||
646  (((tuner_status[i].tuner_type & tuner_type) != 0) && (tuner_status[i].high_count == 0)))
647  {
648  can_tune = TRUE;
649  }
650  }
651 
652  FUNCTION_FINISH(STB_RESCanTuneToTransport);
653 
654  return(can_tune);
655 }
656 
657 /*!**************************************************************************
658  * @brief Returns the number of paths using the tuner
659  * @param tuner_id - tuner
660  * @return Usage count
661  ****************************************************************************/
662 U8BIT STB_RESTunerUsageCount(U8BIT tuner_id)
663 {
664  U8BIT usage_count;
665 
666  FUNCTION_START(STB_RESTunerUsageCount);
667 
668  usage_count = 0;
669 
670  if (res_initialised)
671  {
672  ASSERT(tuner_id < num_tuners);
673 
674  if (tuner_id < num_tuners)
675  {
676  usage_count = tuner_status[tuner_id].usage_count;
677  }
678  }
679 
680  FUNCTION_FINISH(STB_RESTunerUsageCount);
681 
682  return(usage_count);
683 }
684 
685 /*!**************************************************************************
686  * @brief Returns the number of demux paths under the control of the resource manager
687  * @return Number of demux paths
688  ****************************************************************************/
689 U8BIT STB_RESNumDemuxes(void)
690 {
691  FUNCTION_START(STB_RESNumDemuxes);
692  FUNCTION_FINISH(STB_RESNumDemuxes);
693  return(num_demuxes);
694 }
695 
696 /*!**************************************************************************
697  * @brief Acquires a demux path and marks it as being used
698  * @param demux_id - id of existing demux, or INVALID_RES_ID if a new one is to be acquired
699  * @param caps - required capabilities, or 0 if an existing demux is being acquired
700  * @return ID of the demux path acquired, or INVALID_RES_ID if none are available
701  ****************************************************************************/
702 U8BIT STB_RESAcquireDemux(U8BIT demux_id, U16BIT caps)
703 {
704  U8BIT i;
705 
706  FUNCTION_START(STB_RESAcquireDemux);
707 
708  if (res_initialised)
709  {
710  STB_RES_DBG(("STB_RESAcquireDemux(%u, %u)", demux_id, caps));
711 
712  if (demux_id == INVALID_RES_ID)
713  {
714  for (i = 0; (i < num_demuxes) && (demux_id == INVALID_RES_ID); i++)
715  {
716  if ((demux_status[i].usage_count == 0) && ((demux_status[i].caps & caps) == caps))
717  {
718  demux_status[i].usage_count = 1;
719  demux_id = i;
720  }
721  }
722 
723  if ((demux_id == INVALID_RES_ID) && (caps == DMX_CAPS_MONITOR_SI))
724  {
725  /* No demux available for monitoring SI data, so see if a live demux is available
726  * as this will be able to do the same task */
727  for (i = 0; (i < num_demuxes) && (demux_id == INVALID_RES_ID); i++)
728  {
729  if ((demux_status[i].usage_count == 0) && ((demux_status[i].caps & DMX_CAPS_LIVE) != 0))
730  {
731  demux_status[i].usage_count = 1;
732  demux_id = i;
733  }
734  }
735  }
736  }
737  else
738  {
739  /* Acquiring a specific demux, increment its usage count */
740  demux_status[demux_id].usage_count++;
741  }
742  }
743  else
744  {
745  demux_id = INVALID_RES_ID;
746  }
747 
748 #ifdef STB_RES_DEBUG
749  if (demux_id == INVALID_RES_ID)
750  {
751  STB_RES_DBG(("STB_RESAcquireDemux: Failed to acquire a demux"));
752  }
753  else
754  {
755  STB_RES_DBG(("STB_RESAcquireDemux: Acquired %u, usage_count=%u", demux_id,
756  demux_status[demux_id].usage_count));
757  }
758 #endif
759 
760  FUNCTION_FINISH(STB_RESAcquireDemux);
761 
762  return(demux_id);
763 }
764 
765 /*!**************************************************************************
766  * @brief Releases a previously acquired demux path
767  * @param demux_id - ID of the demux path to be released
768  * @return None
769  ****************************************************************************/
770 void STB_RESReleaseDemux(U8BIT demux_id)
771 {
772  FUNCTION_START(STB_RESReleaseDemux);
773 
774  if (res_initialised)
775  {
776  ASSERT(demux_id < num_demuxes);
777 
778  if (demux_id < num_demuxes)
779  {
780  STB_RES_DBG(("STB_RESReleaseDemux(%u): usage_count=%u", demux_id,
781  demux_status[demux_id].usage_count));
782 
783  if (demux_status[demux_id].usage_count > 0)
784  {
785  demux_status[demux_id].usage_count--;
786  STB_RES_DBG(("STB_RESReleaseDemux: Released demux %d", demux_id));
787  }
788 #ifdef STB_RES_DEBUG
789  else
790  {
791  STB_RES_DBG(("STB_RESReleaseDemux: Demux %d released too many times!", demux_id));
792  }
793 #endif
794  }
795  }
796 
797  FUNCTION_FINISH(STB_RESReleaseDemux);
798 }
799 
800 /*!**************************************************************************
801  * @brief Returns the capability flags for the given demux
802  * @param demux_id - demux
803  * @return Capability flags, 0 for invalid demux
804  ****************************************************************************/
805 U16BIT STB_RESGetDemuxCaps(U8BIT demux_id)
806 {
807  U16BIT caps;
808 
809  FUNCTION_START(STB_RESGetDemuxCaps);
810 
811  if (demux_id != INVALID_RES_ID)
812  {
813  caps = demux_status[demux_id].caps;
814  }
815  else
816  {
817  caps = 0;
818  }
819 
820  FUNCTION_FINISH(STB_RESGetDemuxCaps);
821 
822  return(caps);
823 }
824 
825 /*!**************************************************************************
826  * @brief Returns the number of audio decoders in the system
827  * @return Number of audio decoders
828  ****************************************************************************/
830 {
831  FUNCTION_START(STB_RESNumAudioDecoders);
832  FUNCTION_FINISH(STB_RESNumAudioDecoders);
833  return(num_audio_decoders);
834 }
835 
836 /*!**************************************************************************
837  * @brief Acquires an AD decoder and marks it as used
838  * @param None
839  * @return ID of the decoder, or INVALID_RES_ID if none are available
840  ****************************************************************************/
842 {
843  U8BIT i;
844  U8BIT decoder_id = INVALID_RES_ID;
845  FUNCTION_START(STB_RESAcquireADDecoder);
846  if (res_initialised)
847  {
848  for (i = 0; (i < num_audio_decoders) && (decoder_id == INVALID_RES_ID); i++)
849  {
850  if (!ad_decoder_status[i].is_acquired)
851  {
852  ad_decoder_status[i].is_acquired = TRUE;
853  decoder_id = i;
854  STB_RES_DBG(("STB_RESAcquireADDecoder: Decoder %d acquired", decoder_id));
855  }
856  }
857  }
858 #ifdef STB_RES_DEBUG
859  if (decoder_id == INVALID_RES_ID)
860  {
861  STB_RES_DBG(("STB_RESAcquireADDecoder: Failed to acquire a decoder"));
862  }
863 #endif
864 
865  FUNCTION_FINISH(STB_RESAcquireADDecoder);
866 
867  return(decoder_id);
868 }
869 
870 /*!**************************************************************************
871  * @brief Releases a previously acquired AD decoder
872  * @param decoder_id - ID of the decoder
873  * @return None
874  ****************************************************************************/
875 void STB_RESReleaseADDecoder(U8BIT decoder_id)
876 {
877  FUNCTION_START(STB_RESReleaseADDecoder);
878 
879  if (res_initialised)
880  {
881  if (decoder_id < num_audio_decoders)
882  {
883  ad_decoder_status[decoder_id].is_acquired = FALSE;
884  STB_RES_DBG(("STB_RESReleaseADDecoder: Released decoder %d", decoder_id));
885  }
886  }
887 
888  FUNCTION_FINISH(STB_RESReleaseADDecoder);
889 }
890 
891 /*!**************************************************************************
892  * @brief Acquires an audio decoder and marks it as used
893  * @param None
894  * @return ID of the decoder, or INVALID_RES_ID if none are available
895  ****************************************************************************/
897 {
898  U8BIT i;
899  U8BIT decoder_id = INVALID_RES_ID;
900 
901  FUNCTION_START(STB_RESAcquireAudioDecoder);
902 
903  if (res_initialised)
904  {
905  for (i = 0; (i < num_audio_decoders) && (decoder_id == INVALID_RES_ID); i++)
906  {
907  if (!audio_decoder_status[i].is_acquired)
908  {
909  audio_decoder_status[i].is_acquired = TRUE;
910  decoder_id = i;
911  STB_RES_DBG(("STB_RESAcquireAudioDecoder: Decoder %d acquired", decoder_id));
912  }
913  }
914  }
915 
916 #ifdef STB_RES_DEBUG
917  if (decoder_id == INVALID_RES_ID)
918  {
919  STB_RES_DBG(("STB_RESAcquireAudioDecoder: Failed to acquire a decoder"));
920  }
921 #endif
922 
923  FUNCTION_FINISH(STB_RESAcquireAudioDecoder);
924 
925  return(decoder_id);
926 }
927 
928 /*!**************************************************************************
929  * @brief Releases a previously acquired audio decoder
930  * @param decoder_id - ID of the decoder
931  * @return None
932  ****************************************************************************/
933 void STB_RESReleaseAudioDecoder(U8BIT decoder_id)
934 {
935  FUNCTION_START(STB_RESReleaseAudioDecoder);
936 
937  if (res_initialised)
938  {
939  ASSERT(decoder_id < num_audio_decoders);
940 
941  if (decoder_id < num_audio_decoders)
942  {
943  audio_decoder_status[decoder_id].is_acquired = FALSE;
944  STB_RES_DBG(("STB_RESReleaseAudioDecoder: Released decoder %d", decoder_id));
945  }
946  }
947 
948  FUNCTION_FINISH(STB_RESReleaseAudioDecoder);
949 }
950 
951 /*!**************************************************************************
952  * @brief Returns the number of video decoders in the system
953  * @param None
954  * @return Number of video decoders
955  ****************************************************************************/
957 {
958  FUNCTION_START(STB_RESNumVideoDecoders);
959  FUNCTION_FINISH(STB_RESNumVideoDecoders);
960  return(num_video_decoders);
961 }
962 
963 /*!**************************************************************************
964  * @brief Acquires a video decoder and marks it as used
965  * @param None
966  * @return ID of the decoder, or INVALID_RES_ID if none are available
967  ****************************************************************************/
969 {
970  U8BIT i;
971  U8BIT decoder_id = INVALID_RES_ID;
972 
973  FUNCTION_START(STB_RESAcquireVideoDecoder);
974 
975  if (res_initialised)
976  {
977  for (i = 0; (i < num_video_decoders) && (decoder_id == INVALID_RES_ID); i++)
978  {
979  if (!video_decoder_status[i].is_acquired)
980  {
981  video_decoder_status[i].is_acquired = TRUE;
982  decoder_id = i;
983  STB_RES_DBG(("STB_RESAcquireVideoDecoder: Decoder %d acquired", decoder_id));
984  }
985  }
986  }
987 
988 #ifdef STB_RES_DEBUG
989  if (decoder_id == INVALID_RES_ID)
990  {
991  STB_RES_DBG(("STB_RESAcquireVideoDecoder: Failed to acquire a decoder"));
992  }
993 #endif
994 
995  FUNCTION_FINISH(STB_RESAcquireVideoDecoder);
996 
997  return(decoder_id);
998 }
999 
1000 /*!**************************************************************************
1001  * @brief Releases a previously acquired video decoder
1002  * @param decoder_id - ID of decoder
1003  * @return None
1004  ****************************************************************************/
1005 void STB_RESReleaseVideoDecoder(U8BIT decoder_id)
1006 {
1007  FUNCTION_START(STB_RESReleaseVideoDecoder);
1008 
1009  if (res_initialised)
1010  {
1011  ASSERT(decoder_id < num_video_decoders);
1012 
1013  if (decoder_id < num_video_decoders)
1014  {
1015  video_decoder_status[decoder_id].is_acquired = FALSE;
1016  STB_RES_DBG(("STB_RESReleaseVideoDecoder: Released decoder %d", decoder_id));
1017  }
1018  }
1019 
1020  FUNCTION_FINISH(STB_RESReleaseVideoDecoder);
1021 }
1022 
1023 /*!**************************************************************************
1024  * @brief Returns the number of CI slots under the control of the resource manager
1025  * @return Number of CI slots
1026  ****************************************************************************/
1028 {
1029  FUNCTION_START(STB_RESNumCISlots);
1030  FUNCTION_FINISH(STB_RESNumCISlots);
1031  return(num_ci_slots);
1032 }
1033 
1034 #ifdef COMMON_INTERFACE
1035 /*!**************************************************************************
1036  * @brief Acquires a CI slot
1037  * @param service - service the slot will be used for
1038  * @param pmt_data - raw PMT data for the service
1039  * @param ci_protection_desc - raw CI protection descriptor for the service
1040  * @return ID of the CI slot acquired, or INVALID_RES_ID if none are available
1041  ****************************************************************************/
1042 U8BIT STB_RESAcquireCISlot(void *service, U8BIT *pmt_data, U8BIT *ci_protection_desc)
1043 {
1044  U8BIT i;
1045  U8BIT slot_id = INVALID_RES_ID;
1046 
1047  FUNCTION_START(STB_RESAcquireCISlot);
1048 
1049  if (res_initialised)
1050  {
1051  /* See if a CI slot is already being used for this service */
1052  for (i = 0; (i < num_ci_slots) && (slot_id == INVALID_RES_ID); i++)
1053  {
1054  if ((ci_slot_status[i].usage_count > 0) && (ci_slot_status[i].service == service))
1055  {
1056  /* This slot is already being used for this service, so reuse it */
1057  ci_slot_status[i].usage_count++;
1058  slot_id = i;
1059  STB_RES_DBG(("STB_RESAcquireCISlot: CI slot %u acquired, usage_count=%u", slot_id,
1060  ci_slot_status[i].usage_count));
1061  }
1062  }
1063 
1064  /* Acquire a slot if one hasn't already been found */
1065  for (i = 0; (i < num_ci_slots) && (slot_id == INVALID_RES_ID); i++)
1066  {
1067  if (ci_slot_status[i].usage_count == 0)
1068  {
1069  if (STB_CiCcIsServiceAllowed(i, ci_protection_desc))
1070  {
1071  ci_slot_status[i].usage_count = 1;
1072  ci_slot_status[i].service = service;
1073  slot_id = i;
1074  STB_RES_DBG(("STB_RESAcquireCISlot: CI slot %u acquired for service %p", slot_id, service));
1075  }
1076  }
1077  }
1078  }
1079 
1080 #ifdef STB_RES_DEBUG
1081  if (slot_id == INVALID_RES_ID)
1082  {
1083  STB_RES_DBG(("STB_RESAcquireCISlot: Failed to acquire a CI slot for service %p", service));
1084  }
1085 #endif
1086 
1087  FUNCTION_FINISH(STB_RESAcquireCISlot);
1088 
1089  return(slot_id);
1090 }
1091 
1092 /*!**************************************************************************
1093  * @brief Set the given CI slot as acquired and in use
1094  * @param slot_id - ID of the CI slot
1095  * @return TRUE if the slot isn't currently being used, FALSE otherwise
1096  ****************************************************************************/
1097 BOOLEAN STB_RESUseCISlot(U8BIT slot_id)
1098 {
1099  BOOLEAN retval;
1100 
1101  FUNCTION_START(STB_RESUseCISlot);
1102 
1103  retval = FALSE;
1104 
1105  if (res_initialised && (slot_id < num_ci_slots))
1106  {
1107  STB_RES_DBG(("STB_RESUseCISlot(%u): usage count=%u", slot_id,
1108  ci_slot_status[slot_id].usage_count));
1109 
1110  if (ci_slot_status[slot_id].usage_count == 0)
1111  {
1112  ci_slot_status[slot_id].usage_count = 1;
1113  ci_slot_status[slot_id].service = NULL;
1114  retval = TRUE;
1115  }
1116  }
1117 
1118  FUNCTION_FINISH(STB_RESUseCISlot);
1119 
1120  return(retval);
1121 }
1122 
1123 #endif /*COMMON_INTERFACE*/
1124 
1125 /*!**************************************************************************
1126  * @brief Returns the number of times the given slot is in use
1127  * @param slot_id - ID of the CI slot
1128  * @return Slot usage count
1129  ****************************************************************************/
1130 U8BIT STB_RESGetCISlotUsageCount(U8BIT slot_id)
1131 {
1132  U8BIT retval;
1133 
1134  FUNCTION_START(STB_RESGetCISlotUsageCount);
1135 
1136  retval = 0;
1137 
1138  if (res_initialised)
1139  {
1140  ASSERT(slot_id < num_ci_slots);
1141 
1142  if (slot_id < num_ci_slots)
1143  {
1144  retval = ci_slot_status[slot_id].usage_count;
1145  }
1146  }
1147 
1148  FUNCTION_FINISH(STB_RESGetCISlotUsageCount);
1149 
1150  return(retval);
1151 }
1152 
1153 /*!**************************************************************************
1154  * @brief Releases a previously acquired CI slot
1155  * @param slot_id - ID of the CI slot to be released
1156  ****************************************************************************/
1157 void STB_RESReleaseCISlot(U8BIT slot_id)
1158 {
1159  FUNCTION_START(STB_RESReleaseCISlot);
1160 
1161  if (res_initialised)
1162  {
1163  ASSERT(slot_id < num_ci_slots);
1164 
1165  if (slot_id < num_ci_slots)
1166  {
1167  STB_RES_DBG(("STB_RESReleaseCISlot(%u): usage_count=%u", slot_id,
1168  ci_slot_status[slot_id].usage_count));
1169 
1170  if (ci_slot_status[slot_id].usage_count > 0)
1171  {
1172  ci_slot_status[slot_id].usage_count--;
1173  }
1174 
1175  if (ci_slot_status[slot_id].usage_count == 0)
1176  {
1177  ci_slot_status[slot_id].service = NULL;
1178  }
1179  }
1180  }
1181 
1182  FUNCTION_FINISH(STB_RESReleaseCISlot);
1183 }
1184 
U16BIT STB_TuneGetSignalType(U8BIT path)
Gets the signal types of the given tuner path. This will be a bitmask of supported types defined by E...
U8BIT STB_RESNumDemuxes(void)
Returns the number of demux paths under the control of the resource manager.
Definition: stbresmgr.c:689
void * STB_GetMemory(U32BIT bytes)
Attempts to allocate memory from the heap.
Definition: stbheap.c:221
void STB_RESReleaseAudioDecoder(U8BIT decoder_id)
Releases a previously acquired audio decoder.
Definition: stbresmgr.c:933
U8BIT STB_HWGetTunerPaths(void)
Returns the number of front end (Tuner) paths on the platform.
void STB_RESSetTunerDisabled(U8BIT tuner_id, BOOLEAN disable)
Set the disable state for a tuner. When disabled, a tuner will be ignored when acquiring a new tuner ...
Definition: stbresmgr.c:457
BOOLEAN STB_RESCanTuneToTransport(E_STB_DP_SIGNAL_TYPE tuner_type, void *transport)
Returns whether there&#39;s a tuner available to tune to the given transport.
Definition: stbresmgr.c:633
BOOLEAN STB_RESInitialise(void)
Creates and initialises control structures for the resources to be managed.
Definition: stbresmgr.c:117
Header file - macros and function prototypes for public use.
void STB_RESSetTunerOwner(U8BIT tuner_id, E_STB_DP_RES_OWNER owner)
Sets the owner of the tuner.
Definition: stbresmgr.c:532
U8BIT STB_RESAcquireADDecoder(void)
Acquires an AD decoder and marks it as used.
Definition: stbresmgr.c:841
U16BIT STB_DMXGetCapabilities(U8BIT path)
Returns the capability flags of the given demux.
U16BIT STB_RESGetDemuxCaps(U8BIT demux_id)
Returns the capability flags for the given demux.
Definition: stbresmgr.c:805
U8BIT STB_RESAcquireDemux(U8BIT demux_id, U16BIT caps)
Acquires a demux path and marks it as being used.
Definition: stbresmgr.c:702
void * STB_RESGetTunedTransport(U8BIT tuner_id)
Returns the transport record saved with the specified tuner.
Definition: stbresmgr.c:606
E_STB_DP_SIGNAL_TYPE STB_RESGetTunerType(U8BIT tuner_id)
Returns the type of the given tuner.
Definition: stbresmgr.c:554
CI Content Control.
BOOLEAN STB_RESIsTunerDisabled(U8BIT tuner_id)
Returns whether a tuner has been disabled or not.
Definition: stbresmgr.c:479
U8BIT STB_RESNumVideoDecoders(void)
Returns the number of video decoders in the system.
Definition: stbresmgr.c:956
U8BIT STB_HWGetVideoDecodePaths(void)
Returns the number of video decoding paths on the platform.
U8BIT STB_RESNumAudioDecoders(void)
Returns the number of audio decoders in the system.
Definition: stbresmgr.c:829
Debug functions header file.
Header file - macros and function prototypes for public use.
U8BIT STB_RESAcquireAudioDecoder(void)
Acquires an audio decoder and marks it as used.
Definition: stbresmgr.c:896
void STB_RESReleaseADDecoder(U8BIT decoder_id)
Releases a previously acquired AD decoder.
Definition: stbresmgr.c:875
U8BIT STB_HWGetAudioDecodePaths(void)
Returns the number of audio decoding paths on the platform.
void STB_RESReleaseDemux(U8BIT demux_id)
Releases a previously acquired demux path.
Definition: stbresmgr.c:770
System Wide Global Technical Data Type Definitions.
void STB_TuneSetSignalType(U8BIT path, E_STB_TUNE_SIGNAL_TYPE type)
This function is only relevant for tuners that support more than one signal type; for tuners that don...
STB middleware resource management module header file.
U8BIT STB_RESNumCISlots(void)
Returns the number of CI slots under the control of the resource manager.
Definition: stbresmgr.c:1027
U8BIT STB_RESAcquireVideoDecoder(void)
Acquires a video decoder and marks it as used.
Definition: stbresmgr.c:968
Header file - Function prototypes for heap memory.
void STB_RESSetTunedTransport(U8BIT tuner_id, void *t_ptr)
Saves the transport pointer with the specified tuner.
Definition: stbresmgr.c:583
U8BIT STB_RESNumEnabledTuners(void)
Returns the number of tuners that aren&#39;t disabled.
Definition: stbresmgr.c:506
void STB_RESReleaseTuner(U8BIT tuner_id, BOOLEAN high_priority, E_STB_DP_RES_OWNER owner)
Releases a tuner that has previously been acquired.
Definition: stbresmgr.c:404
Header file - Function prototypes for Demux control.
U8BIT STB_HWGetDemuxPaths(void)
Queries the number of demux paths available.
U8BIT STB_RESNumTuners(void)
Returns the number of tuners.
Definition: stbresmgr.c:279
U8BIT STB_RESAcquireTuner(E_STB_DP_SIGNAL_TYPE tuner_type, void *transport, E_STB_DP_RES_OWNER owner, BOOLEAN high_priority, BOOLEAN *tuner_taken)
Acquires a tuner. Tuners will be reused if possible.
Definition: stbresmgr.c:297
void STB_RESReleaseCISlot(U8BIT slot_id)
Releases a previously acquired CI slot.
Definition: stbresmgr.c:1157
U8BIT STB_RESTunerUsageCount(U8BIT tuner_id)
Returns the number of paths using the tuner.
Definition: stbresmgr.c:662
BOOLEAN STB_CiCcIsServiceAllowed(U8BIT slot_id, U8BIT *ci_prot_desc)
Tell whether the service is allowed. This function checks whether the CI Protection Descriptor allows...
Definition: stbcicc.c:349
void STB_RESReleaseVideoDecoder(U8BIT decoder_id)
Releases a previously acquired video decoder.
Definition: stbresmgr.c:1005
U8BIT STB_RESGetCISlotUsageCount(U8BIT slot_id)
Returns the number of times the given slot is in use.
Definition: stbresmgr.c:1130
Header file - Function prototypes for tuner control.