This document describes the various modules within DVBCore and how they should be used when developing a user interface. Any references made to the “application” within this document relate to the software developed that includes the user interface, whether this is statically linked to the DVB libraries or is running as a separate process. Details of the functions mentioned here can be found in the DVBCore DVB API document.
There are many cases where the DVB functions return arrays or lists of items and wherever possible these should always be freed using the appropriate release function, e.g. ACFG_ReleaseCountryList should be used to free the country list obtained by calling ACFG_GetCountryList.
C data types vary in size for different processors, so in order to ensure portability the following standard types are defined. These types are used by the DVBCore and so must be used when making a call to DVBCore in place of the standard C types. The types are defined in a file techtype.h. The following types are defined:
U8BIT unsigned byte integer value
U16BIT unsigned 2-byte integer value
U32BIT unsigned 4-byte integer value
S8BIT signed byte integer value
S16BIT signed 2-byte integer value
S32BIT signed 4-byte integer value
BOOLEAN single byte with values 0 (i.e. FALSE) or 1 (i.e. TRUE)
All strings returned by the DVB library are DVB SI strings as defined in appendix A of ETSI document EN 300 468. DVBCore includes functions to convert (STB_ConvertStringToUnicode) and manipulate DVB strings to return them in DVB UTF-16 format, in which the first byte is 0x11 to identify it as UTF-16. The string functions are defined in stbuni.h and they all detect the format of the strings passed to them, converting them if necessary and returning strings in UTF-16 format.
There is a single function that must be called to initialise DVBCore before any other DVB related functions are called, which is:
BOOLEAN APP_InitialiseDVB(U8BIT* app_nvm_data, U32BIT app_nvm_data_size, void (*event_handler)(U32BIT event, void* event_data, U32BIT data_size))
This function results in the DVB and associated hardware abstraction layer (platform) code being initialised and background tasks to start running. Once this function has been called, the application may start receiving events via the registered event callback function at any time.
Along with any data defined by the application in the above call when DVBCore is initialised, the DVB also stores some data in non-volatile memory and the application can access these either by calling a function that results in the item being accessed or by reading them explicitly using APP_NvmRead. The app can also change the values of saved items using APP_NvmWrite, but although accessible, not all items should be considered to be under the direct control of the app. When first started, the DVB includes a default set of item values. The list of all items is defined in app_nvm.h.
DVBCore includes configuration settings for many countries and these settings define information that is required when scanning for services, processing SI data and various other runtime operations. Where support for more than one country is provided it needs to be told which country is “active” to ensure it uses the correct information for these operations.
Even when support for only one country is provided, that country may include multiple regions and/or define more than one language as being available for audio and/or subtitles. Once set, these values are saved in non-volatile memory (defined above), so don’t need to be set each time the app is run.
Unless the default country, region and/or audio language are known to be acceptable, the available options are normally presented to the user before DVBCore is requested to scan for services, and the following functions are available to build this user interface.
To see how many countries are supported by the DVB, call ACFG_GetNumCountries, and to get a list of the names of the available countries, use ACFG_GetCountryList. Countries are referenced using a country_id value, which is the index of the country in the list returned by ACFG_GetCountryList. Once a country has been set, the current country_id can be retrieved using ACFG_GetCountryId, with equivalent functions for the region and language ids.
Even if there’s only one country, that country may include multiple regions, so use ACFG_GetNumRegions and ACFG_GetRegionList, as required. And to present the list of available audio languages defined for a country, use ACFG_GetNumDbLanguages and ACFG_GetDbLangList.
If any of the above list functions only contain a single item then 0 should be used as that item’s id value.
Once all selections have been made, ACFG_SetCountryId can be used to set the values. All functions are defined in ap_cfg.h.
DVBCore supports auto and manual search modes, with the list of frequencies and other tuning parameters that will be used coming from built-in tables defined for each country. Features such as whether frequency or network type searches should be performed, and whether free-to-air, scrambled or all services should be stored (ASI_SetSearchServiceType) are also available.
There are a number of functions that can be used to start a service scan, with ACTL_StartServiceSearch being used to start an auto scan controlled by the tuning table obtained from the country information. If a frequency scan is started, then each frequency defined in the tuning table will be tuned to in turn, but if a network scan is started then a frequency scan will be performed until an NIT is found, after which the scanned frequencies will be those defined in the NIT. Consequently, the number of frequencies to be scanned, and hence the search progress, may jump backwards or forwards during a network search after the NIT is found, as the number of frequencies to be scanned may change.
Manual scans can be started using either ACTL_StartManualSeachById, where the id is an index into the country’s tuning table, or ACTL_StartManualSearch, where the tuning parameters are explicitly specified by the app. With both of these calls, a search will normally just be performed on the defined frequency, but as above, if a network search is requested and an NIT is found, then many more frequencies may end needing to be searched.
Searching for services using a satellite tuner is currently only supported through the use of ACTL_StartManualSearch with the tuning parameters being provided by the app. However, if a network search is started on a valid transponder frequency that includes a network table, then a full set of services will be found.
Whichever search function is used to start a scan, and assuming the scan starts successfully, the following basic operations should be performed by the application to monitor the progress of the scan whenever it receives the UI_EVENT_UPDATE event, which will be sent to the app each time there’s new information available from the DVB that may want to be presented to the user. This may just be an update to the progress indication, which can be queried using ACTL_GetSearchProgress, or because the search has completed or new transports and/or services have been found. The following is a simple example of a typical sequence of calls that and app would make on receiving UI_EVENT_UPDATE:
if (ACTL_IsSearchComplete()) { if (is_manual_search) { /* Only needs to be called for a manual search */ ACTL_FinishManualSearch(TRUE); } /* Exit search */ } else { /* Update search progress */ progress = ACTL_GetSearchProgress(); /* Update list of available services */ ADB_GetServiceList(ADB_SERVICE_LIST_ALL, &serv_list, &num_servs); if (num_servs != 0) { /* Get service list names to present to user */ serv_names = ADB_GetServiceListFullNames(serv_list, num_servs, FALSE); /* Update UI with list of service names */ /* Free service info */ ADB_ReleaseServiceListNames(serv_names, num_servs); ADB_ReleaseServiceList(serv_list, num_servs); } }
The functions that need to be called to stop and/or complete a service search will depend on how it was started and whether the scan was interrupted or allowed to run to completion. It’s at this stage that LCNs will be assigned.
In the case of an auto service search that runs to completion, no function calls are required to complete the scan. However, if the scan is stopped before completing then it’s possible to specify whether the services found so far should be saved or discarded by calling ACTL_StopServiceSearch, passing TRUE (save) or FALSE (discard) as an argument.
For a country such as the UK that uses target region descriptors as a means of assigning LCNs for regionalised services, additional steps may also be needed depending on whether there were any services requesting the same LCN, but finally ACTL_CompleteServiceSearch should be called to ensure all the steps are performed to complete the search correctly.
For a manual scan, ACTL_FinishManualSearch should be called whether the scan completed or is being stopped, with the argument defining whether the found services should be saved (TRUE) or discarded (FALSE).
Access to the database maintained by DVBCore is through the set of ADB_ functions that are defined in ap_dbacc.h. These functions provide access to all network, transport/transponder and service records that are discovered during service searches, along with information that is monitored when running, such as service PIDs, EPG event information for each service, availability of DVB and/or teletext subtitles, etc., and if required, access to the stream lists for each service.
Event data from the EIT tables is saved with the relevant service, with the data from the EITp/f tables being saved as “now” and “next” events for a service and EITsched being saved as a separate list of events. There are three main functions to access the event information for a service, ADB_GetNowNextEvents, ADB_GetEventSchedule and ADB_GetEventScheduleByGenre. These functions always return copies of the events, so these should be freed when no longer required, using ADB_ReleaseEventData for single events such as now/next, or ADB_ReleaseEventList for multiple events such as the schedule.
When getting the event schedule, if old events aren’t requested then the first two events that will be included in the returned list will be the now and/or next events, if these are available, because these are normally updated frequently and so are more accurate when there are changes to the schedule, perhaps due to a programme overrunning.
Searches of the EPG data can be performed based on text contained in the title, description and/or extended description, using a match string that can be seen as a set of tokens or an exact string that has to be matched. These searches can also be restricted based on days and/or times, so only events within the restricted times will be returned.
A search is performed by calling AGS_OpenSearch, followed by multiple calls to AGS_GetNextResult and finally AGS_CloseSearch, which are all defined in ap_epgsearch.h.
DVBCore implements resource management for tuners, demuxes, decoders, etc, using an object called a “decode path” (often referred to simply as a path in the code and this doc), which is effectively a “handle” to a set of resources that are acquired to perform a particular function, such as watching live TV, recording or playing back a recording, etc. The “live path” is a decode path that has been acquired to tune to a live broadcast signal and, optionally, decode it for output on the screen. Other types of path that can be acquired are recording paths, used when recording on a PVR product, and a playback path for playing back recordings on a PVR. The actual number of decode paths available will be platform specific and will depend on whether PVR functions are provided.
If some form of conditional access system, such as CI+ or Conax, is being used with the DVB, then the resources associated with these are also managed using the decode path.
There are a number of functions to acquire, release and query decode paths in stbdpc.h, but for acquiring a live path to view a service a simple convenience function is provided, ACTL_AcquireLivePathForService, defined in ap_cntrl.h, which will ensure the correct type of tuner is acquired in order to view the service.
As decode paths are used for resource management, it’s important that they’re also released by the app when no longer required. For the live path, ACTL_ReleaseLivePathForService is available, which is described below, but STB_DPReleaseLivePath, STB_DPReleaseRecordingPath and STB_DPReleasePlaybackPath are also available. On a system where multiple tuner types are available, or a conditional access system is being used, an app should release and reacquire the live path whenever the service being viewed is changed to ensure the correct resources are assigned to the path.
Tuning to a service in order to watch a live broadcast signal can be achieved with a couple of function calls, of which the first is to acquire a live path using the function ACTL_AcquireLivePathForService, followed by ACTL_TuneToService. This last function will result in the app receiving a number of events, some of which may be used by the app to provide status information to the user, but none of which need to be handled to view the service as these are all dealt with by the DVB code.
There are a number of processes that are started when viewing a service and each resource type involved is also typically monitored to maintain a state. So the state of the tuner is monitored through events sent from the platform that determine whether it’s locked or not locked, and similarly with the decoders to monitor whether they’re disabled, enabled, starting or whether decoding has started. Also when successfully tuned, SI tables will start to be monitored. Consequently, the live path should never simply be released, but functions must be called to stop any background processes and/or to ensure the resource is aware that its state is being changed.
The best function to call to release the live path is ACTL_ReleaseLivePathForService, which will ensure that the appropriate tuning, decoding and SI functions are called to set the relevant states before the path is released.
However, if this function can’t be used then STB_DPReleaseLivePath can be used, but this must be preceded by functions to control the state of the resources, which can either be to just call ACTL_TuneOff, which will also stop decoding and the SI process, or if the tuner may also be being used for something else (e.g. recording) then ACTL_DecodeOff and STB_DPStopSI should both be called.
Changing channel can simply be achieved by stopping and releasing the current decode path using either of the methods described above, followed by calls to the same functions used to tune to the service in the first place, i.e. ACTL_AcquireLivePathForService to acquire a new path, and then ACTL_TuneToService.
Both DVB and EBU Teletext subtitles are controlled using the same set of functions and if both are available for a particular service then DVB subtitles will be preferred. To query whether a service has subtitles, use ADB_ServiceHasSubtitles, which also indicates whether they are DVB or teletext subtitles.
The processing and display of subtitles, if available, is started using ACTL_StartSubtitles and stopped using ACTL_StopSubtitles. If subtitles are still to be processed but not displayed, then ACTL_PauseSubtitles is used, with ACTL_ResumeSubtitles being used to redisplay them.
If subtitles are started but they aren’t currently being broadcast for a service then they’ll be automatically started when they become available.
Finally, ACTL_AreSubtitlesStarted and ACTL_AreSubtitlesDisplayed can be used to query the subtitle state at any time.
The availability of teletext for a service is queried using ADB_GetRequiredTtextPid, which also returns the default magazine and page. This function will return 0 if teletext isn’t available.
The level of page caching can be controlled using STB_EBUTT_SetCacheMethod, with teletext processing being started using STB_EBUTT_Start and then displayed using STB_EBUTT_Show.
Once teletext is displayed, certain key presses need to be passed to the teletext decoder to allow the user to control what’s being displayed and the function to use for this is STB_EBUTT_NotifyEvent.
To stop teletext from being shown, use STB_EBUTT_Hide, and to stop teletext processing use STB_EBUTT_Stop.
DVBCore provides three types of timers that are available to an app, sleep, alarm and PVR recording types. All timers are created the same way, which is by means of a structure called S_TIMER defined in ap_tmr.h.
All timers require the type and name to be set, though the name isn’t mandatory but is helpful if there’s likely to be more than one of that timer type created and the timer name will be presented to the user.
A timer’s date and time should be set in local time.
PVR recording timers are handled by DVBCore, but sleep and alarm timers will only work if code is added to the app to handle them.
Sleep timers use the type TMR_TYPE_SLEEP and just require the start date and time to be set in the structure. Typically this is the date/time that the box will go into standby, but the app needs to be involved for this to happen, so the handling of this type of timer is left entirely to the app and as such it can choose to do whatever it wants when a sleep timer is triggered.
To handle a sleep timer the app has to handle the STB_EVENT_TIMER_EXPIRE event and call ATMR_IsSleepTimerToBeStarted. If this returns TRUE then ATMR_SleepStarted should be called after which the app can do whatever it needs to to perform the sleep operation.
Alarm timers use the type TMR_TYPE_ALARM and the following structure entries should be set: start date & time, frequency, is_serv_on, sound_alarm, is_rampv_on, service_id, transport_id and orig_net_id.
To handle an alarm timer the app has to handle the STB_EVENT_TIMER_EXPIRE event and call ATMR_IsAlarmTimerToBeStarted. If this returns TRUE then ATMR_AlarmStarted should be called after which it’s up to the app to use the settings passed back in the S_ALARM structure from ATMR_IsAlarmToBeStarted to change to the service indicated. It would also be up to the app to display a message to the user informing them of the service change.
For timers such as the alarm and PVR timers (see below) where service IDs need to be set and maybe the date and time taken from an event, ATMR_InitialiseTimer can be used to set these values in the structure. If NULL is given for the service then the current service on the live path will be used, if valid, and if no event is specified then the current date and time will be set in the structure, with a duration of 1 hour. A default name will also be set in the timer structure based on the type of the timer and, for PVR timers, the service name, if valid.
Once all values in the S_TIMER structure have been set ATMR_Add should be called to create the timer.
DVBCore PVR supports recording based on time and/or events in the EIT and these recordings can be made on internal or external disk drives, including USB devices. Although PVR functions are available to create, start and stop recordings, it’s more typical to perform these operations using timers, which is also true for a live recording where the user starts recording the programme they’re currently viewing. Performing these operations through timers has the advantage that a limit will be set for the length of a recording and starting and stopping the recording will be handled automatically by DVBCore.
PVR timers use the type TMR_TYPE_PVR_RECORD and the structure entries that need to be set vary depending on whether the recording should be time based or event based.
The disk that will be used to store a recording is defined by the disk_id value in S_TIMER. ATMR_InitialiseTimer will set this to the default disk id, but this can be set to any valid disk id returned from the platform code.
An additional setting in the S_TIMER structure is available for PVR timers, which is notify_time. This is a value specified in multiples of 3 seconds (max value 255, giving a time of up to 12min 45secs) that will result in an event (STB_EVENT_TIMER_NOTIFY) being sent to the app this length of time before a recording is due to start. This can be used by the app to present a message to the user, perhaps warning them if the service will be changed and could allow them to cancel the recording. The data sent with the event is the timer’s handle.
Setting a timer to perform a recording based on time requires the start date and time to be set, along with the duration of the recording, and the service on which the recording is to take place. If a service is passed into ATMR_InitialiseTimer then the recording will be set for this service and if an event is also passed in then the start date and time and duration from this event will be used to initialise the S_TIMER structure.
The simplest case would be for ATMR_InitialiseTimer to be called followed by ATMR_Add, which for a PVR timer would result in a recording being started immediately on the current service and lasting for 1 hour.
Event based recording is where the triggering for the start and end of a recording is not based on time but on the change of the now event in the EITp/f table. This type of recording results in accurate recordings being produced that should always catch the start and end of any programme, but is only valid if the EIT updates are triggered by changes in events rather than time which requires support from the broadcaster. To set a timer that will do this, an event_id must be specified in S_TIMER and the event_triggered flag must be set, in addition to the settings required for time based recordings.
To get info on recordings currently taking place, all the decode paths need to be queried, calling STB_DPIsRecording, which will return the recording handle, and APVR_GetPathRecordingName can be used to get the name of the recording.
Two functions are available to stop a recording, APVR_StopTunerRecording which will stop a recording on a given path, and APVR_StopRecording which will stop the recording with the given recording handle.
Pausing live TV in DVBCore is achieved by playing back a recording in chase playback mode (i.e. playing the same file that’s being recorded) and is implemented by calling a set sequence of the APVR functions. First the recording has to be started using APVR_StartPauseRecord, which returns the path that will be used for the recording, so if this is returned as INVALID_RES_ID then the recording has failed and pausing isn’t possible. This could be the case if the maximum number of recordings are already taking place.
The app should then wait until it receives the STB_EVENT_PVR_REC_START event, which will have the recording path in the event data, after which APVR_StartPausePlay should be called. This will start the playback, but in paused mode, so the user should then be allowed to control playback in the normal way (i.e. play, fast forward, etc).
There are two additional events that may be received by the app, though these will be platform dependant; STB_EVENT_PVR_PLAY_BOF if the user rewinds to the start of the recording, and STB_EVENT_PVR_PLAY_EOF when playback catches up with the recording.
Stopping pause live mode, and optionally returning to viewing live TV, is achieved by calling APVR_StopPauseRecord.
Depending on the way the platform code is implemented, DVBCore can maintain a list of the recordings that can be played on all available disk drives, whether internal or external, and this list can be dynamically updated as USB devices are attached or removed. To get the list of available recordings for playback use APVR_GetPlayList and to play a recording use APVR_PlayRecording.
Control of playback once started is through the functions APVR_NormalPlay, APVR_PausePlay, APVR_FFPlay, APVR_FRPlay, APVR_SlowMoPlay and APVR_StopPlay.
To display subtitles during playback, the same functions are used as for live TV, so refer to 'Viewing subtitles'.
As much of what happens in a DVB system is of an asynchronous nature, DVBCore is event based. All of these events are passed to an application, but only some of them need to be acted on. Some may be useful in presenting information to a user, such as a “no signal” message when a tuner loses lock. It should also be noted that some of these events are sent by the platform code and so are dependant on the platform being able to provide them, so only the most common events are documented here. Unless otherwise stated, no action is required by the application, but it can use the event to update the UI.
Event Name | Event Data | Notes |
---|---|---|
STB_EVENT_TUNE_LOCKED | U8BIT tuner index | |
STB_EVENT_TUNE_NOTLOCKED | U8BIT tuner index | |
STB_EVENT_AUDIO_DECODE_STARTED | U8BIT decoder index | |
STB_EVENT_AUDIO_DECODE_STOPPED | ||
STB_EVENT_VIDEO_DECODE_STARTED | U8BIT decoder index | |
STB_EVENT_VIDEO_DECODE_STOPPED | U8BIT decoder index | |
STB_EVENT_AD_DECODE_STARTED | U8BIT decoder index | Audio description |
STB_EVENT_AD_DECODE_STOPPED | U8BIT decoder index | |
STB_EVENT_SAMPLE_DECODE_STOPPED | U8BIT decoder index | Audio clip from memory |
STB_EVENT_HDMI_CONNECTED | ||
STB_EVENT_HDMI_DISCONNECTED | ||
STB_EVENT_DISK_CONNECTED | ||
STB_EVENT_DISK_REMOVED | ||
STB_EVENT_DISK_FULL | U16BIT disk id | |
STB_EVENT_PVR_REC_START | U8BIT recording handle | For pause live TV, this indicates that APVR_StartPausePlay can now be called. |
STB_EVENT_PVR_REC_STOP | ||
STB_EVENT_PVR_PLAY_START | U8BIT decoder index | |
STB_EVENT_PVR_PLAY_STOP | U8BIT decoder index | |
STB_EVENT_PVR_PLAY_BOF | U8BIT decoder index | Beginning of file. Some action should be taken, which may be different for normal playback or pause live TV. |
STB_EVENT_PVR_PLAY_EOF | U8BIT decoder index | End of file. Some action should be taken, but may be different for normal playback and pause live TV. |
Event Name | Event Data | Notes |
---|---|---|
STB_EVENT_SEARCH_SUCCESS | U32BIT transport handle | Use to present updated info during a service search |
STB_EVENT_SEARCH_FAIL | Tuner locked but not services were found. | |
STB_EVENT_TIMER_NOTIFY | U32BIT timer handle | Timer will be triggered after the set notification time. Can be used to present a warning to the user, e.g. of an upcoming recording that’s about to start. |
STB_EVENT_TIMER_EXPIRE | U32BIT timer handle | Timer has triggered |
STB_EVENT_DECODE_LOCKED | Decoding is locked. This will be due to parental control being applied and the UI should ask the user for a PIN before unlocking the decoding so it can be started. | |
STB_EVENT_OTA_SW_UPGRADE_FOUND | ||
STB_EVENT_OTA_SW_UPGRADE_NOTFOUND | ||
STB_EVENT_OTA_SW_UPGRADE_DOWNLOADING | Downloading update | |
STB_EVENT_OTA_SW_UPGRADE_BURNING | Writing to flash | |
STB_EVENT_OTA_SW_UPGRADE_ERROR | Error detected, upgrade failed. | |
STB_EVENT_OTA_SW_UPGRADE_COMPLETED | Upgrade successful. | |
UI_EVENT_UPDATE | General event, mostly used during a search of some kind (service, etc), that’s sent when something has changed and the UI can be updated. | |
APP_EVENT_SERVICE_NOT_RUNNING | U8BIT decode path | Current service may be changed if there’s a linkage to an alternative service, so the UI may need to check if the current service has been changed. |
APP_EVENT_SERVICE_RUNNING | U32BIT service handle | A not running service is now running. DVB may change back to this service if it changed away when it became not running. |
APP_EVENT_SERVICE_AUDIO_PID_UPDATE | U32BIT service handle | |
APP_EVENT_SERVICE_VIDEO_PID_UPDATE | U32BIT service handle | |
APP_EVENT_SERVICE_AUDIO_CODEC_CHANGED | U32BIT service handle | |
APP_EVENT_SERVICE_VIDEO_CODEC_CHANGED | U32BIT service handle | |
APP_EVENT_SERVICE_SUBTITLE_UPDATE | U32BIT service handle | Subtitle settings, DVB or teletext, have changed |
APP_EVENT_SERVICE_SCRAMBLE_CHANGE | U32BIT service handle | Scramble state of the service has changed |
APP_EVENT_SERVICE_EIT_NOW_UPDATE | This event is latched, which means that it won’t be sent again until DVBCore indicates it’s handled any previous instance of the same event. For this reason, it won’t necessarily be sent when the now event changes for every service. | |
APP_EVENT_SERVICE_EIT_SCHED_UPDATE | This event is also latched – see above. | |
APP_EVENT_SERVICE_STREAMS_CHANGED | U32BIT service handle | The list of streams for a service have changed |
APP_EVENT_SERVICE_CHANGED | U32BIT service handle | Sent when tuning to a new service and the PMT is received, or if the service being viewed on the live path is changed for some other reason (e.g. the live tuner has been used to start a recording on a different service). |
APP_EVENT_TIME_CHANGED | Sent whenever a TDT or TOT is received. | |
APP_EVENT_PVR_RECORDING_FAILED | Failed to start a recording. |
Event Name | Event Data | Notes |
---|---|---|
STB_EVENT_CI_INSERT | U8BIT slot id | CAM has been inserted |
STB_EVENT_CI_REMOVE | U8BIT slot id | CAM has been ejected |
STB_EVENT_CI_OPEN_MODULE | U32BIT module handle | Request to start an MMI |
STB_EVENT_CI_CLOSE_MODULE | U32BIT module handle | MMI stopped |
STB_EVENT_CI_CAM_UPGRADE_PROGRESS | ||
STB_EVENT_CI_CAM_UPGRADE_FAILED | ||
STB_EVENT_CI_CAM_UPGRADE_COMPLETE | ||
STB_EVENT_CI_REQUEST_OPERATOR_SEARCH | U32BIT module handle | Module is requesting to start an operator search. Present a UI asking the user if the search can be started. |
STB_EVENT_CI_OPERATOR_SEARCH_FINISHED | ||
APP_EVENT_SERVICE_DELETED | U32BIT service handle | A CI+ operator profile service has been deleted. |