From 7d01fdb66ef65de2c5c2beadd79b8faee467b868 Mon Sep 17 00:00:00 2001 From: Henry Fang Date: Fri, 23 Aug 2019 10:31:21 -0700 Subject: [PATCH] Add filter function to Demux interface and Add program info to Descrambler bug: 135708935 Test: Manual Change-Id: Iacaebdac6a8ce08ca47ae272be13d51fbd502959 Merged-In: Iacaebdac6a8ce08ca47ae272be13d51fbd502959 --- tv/tuner/1.0/IDemux.hal | 147 ++++++++++++++++ tv/tuner/1.0/IDemuxCallback.hal | 10 +- tv/tuner/1.0/IDescrambler.hal | 50 +++++- tv/tuner/1.0/ITuner.hal | 1 + tv/tuner/1.0/types.hal | 298 +++++++++++++++++++++++++++++++- 5 files changed, 499 insertions(+), 7 deletions(-) diff --git a/tv/tuner/1.0/IDemux.hal b/tv/tuner/1.0/IDemux.hal index 938bc4456e..2d7b2754ac 100644 --- a/tv/tuner/1.0/IDemux.hal +++ b/tv/tuner/1.0/IDemux.hal @@ -22,6 +22,153 @@ interface IDemux { */ setFrontendDataSource(FrontendId frontendId) generates (Result result); + /** + * Add a filter to the demux + * + * It is used by the client to add a filter to the demux. + * + * @param type the type of the filter to be added. + * @param bufferSize the buffer size of the filter to be added. It's used to + * create a FMQ(Fast Message Queue) to hold data output from the filter. + * @param cb the callback for the filter to be used to send notifications + * back to the client. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + * @return filterId the ID of the newly added filter. + */ + addFilter(DemuxFilterType type, uint32_t bufferSize, IDemuxCallback cb) + generates (Result result, DemuxFilterId filterId); + + /** + * Get the descriptor of the filter's FMQ + * + * It is used by the client to get the descriptor of the filter's Fast + * Message Queue. The data in FMQ is filtered out from MPEG transport + * stream. The data is origanized to data blocks which may have + * different length. The length's information of one or multiple data blocks + * is sent to client throught DemuxFilterEvent. + * + * @param filterId the ID of the filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for wrong filter ID. + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + * @return queue the descriptor of the filter's FMQ + */ + getFilterQueueDesc(DemuxFilterId filterId) + generates (Result result, fmq_sync queue); + + /** + * Configure the filter. + * + * It is used by the client to configure the filter so that it can filter out + * intended data. + * + * @param filterId the ID of the filter. + * @param settings the settings of the filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for wrong filter ID. + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + configureFilter(DemuxFilterId filterId, DemuxFilterSettings settings) + generates(Result result); + + /** + * Start the filter. + * + * It is used by the client to ask the filter to start filterring data. + * + * @param filterId the ID of the filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for wrong filter ID. + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + startFilter(DemuxFilterId filterId) generates (Result result); + + /** + * Stop the filter. + * + * It is used by the client to ask the filter to stop filterring data. + * It won't discard the data already filtered out by the filter. The filter + * will be stopped and removed automatically if the demux is closed. + * + * @param filterId the ID of the filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for wrong filter ID. + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + stopFilter(DemuxFilterId filterId) generates (Result result); + + /** + * Flush the filter. + * + * It is used by the client to ask the filter to flush the data which is + * already produced but not consumed yet. + * + * @param filterId the ID of the filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for wrong filter ID. + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + flushFilter(DemuxFilterId filterId) generates (Result result); + + /** + * Remove a filter from the demux + * + * It is used by the client to remove a filter from the demux. + * + * @param filterId the ID of the removed filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for wrong filter ID. + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + removeFilter(DemuxFilterId filterId) generates (Result result); + + /** + * Get hardware sync ID for audio and video. + * + * It is used by the client to get the hardware sync ID for audio and video. + * + * @param filterId the ID of the filter. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for a wrong filter ID. + * UNKNOWN_ERROR if failed for other reasons. + * @return avSyncHwId the id of hardware A/V sync. + */ + getAvSyncHwId(DemuxFilterId filterId) + generates (Result result, AvSyncHwId avSyncHwId); + + /** + * Get current time stamp to use for A/V sync + * + * It is used by the client to get current time stamp for A/V sync. HW is + * supported to increment and maintain current time stamp. + * + * @param avSyncHwId the hardware id of A/V sync. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_ARGUMENT if failed for a wrong hardware ID of A/V sync. + * UNKNOWN_ERROR if failed for other reasons. + * @return time the current time stamp of hardware A/V sync. The time stamp + * based on 90KHz has the same format as PTS (Presentation Time Stamp). + */ + getAvSyncTime(AvSyncHwId avSyncHwId) + generates (Result result, uint64_t time); + /** * Close the Demux instance * diff --git a/tv/tuner/1.0/IDemuxCallback.hal b/tv/tuner/1.0/IDemuxCallback.hal index c67c5f2aa6..7efd2c3591 100644 --- a/tv/tuner/1.0/IDemuxCallback.hal +++ b/tv/tuner/1.0/IDemuxCallback.hal @@ -6,6 +6,14 @@ interface IDemuxCallback { * * @param filterEvent a demux filter event. */ - oneway onFilterEvent(DemuxFilterEvent filterEvent); + oneway onFilterEvent(DemuxFilterEvent filterEvent); + + /** + * Notify the client a new status of a demux filter. + * + * @param filterId the demux filter ID. + * @param status a new status of the demux filter. + */ + oneway onFilterStatus(DemuxFilterId filterId, DemuxFilterStatus status); }; diff --git a/tv/tuner/1.0/IDescrambler.hal b/tv/tuner/1.0/IDescrambler.hal index 4d6cf3c7a1..d078657d65 100644 --- a/tv/tuner/1.0/IDescrambler.hal +++ b/tv/tuner/1.0/IDescrambler.hal @@ -1,11 +1,9 @@ package android.hardware.tv.tuner@1.0; - /** * Descrambler is used to descramble input data. * */ interface IDescrambler { - /** * Set a demux as source of the descrambler * @@ -13,6 +11,7 @@ interface IDescrambler { * descrambler. A descrambler instance can have only one source, and * this method can be only called once. * + * @param demuxId the id of the demux to be used as descrambler's source. * @return result Result status of the operation. * SUCCESS if successful, * INVALID_STATE if failed for wrong state. @@ -20,6 +19,51 @@ interface IDescrambler { */ setDemuxSource(DemuxId demuxId) generates (Result result); + /** + * Set a key token to link descrambler to a key slot + * + * It is used by the client to link a hardware key slot to a descrambler. + * A descrambler instance can have only one key slot to link, but a key + * slot can hold a few keys for different purposes. + * + * @param keyToken the token to be used to link the key slot. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + setKeyToken(TunerKeyToken keyToken) generates (Result result); + + /** + * Add packets' PID to the descrambler for descrambling + * + * It is used by the client to specify Package ID (PID) of packets which the + * descrambler start to descramble. Multiple PIDs can be added into one + * descrambler instance because descambling can happen simultaneously on + * packets from different PIDs. + * + * @param pid the PID of packets to start to be descrambled. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + addPid(DemuxTpid pid) generates (Result result); + + /** + * Remove packets' PID from the descrambler + * + * It is used by the client to specify Package ID (PID) of packets which the + * descrambler stop to descramble. + * + * @param pid the PID of packets to stop to be descrambled. + * @return result Result status of the operation. + * SUCCESS if successful, + * INVALID_STATE if failed for wrong state. + * UNKNOWN_ERROR if failed for other reasons. + */ + removePid(DemuxTpid pid) generates (Result result); + /** * Release the descrambler instance * @@ -30,6 +74,6 @@ interface IDescrambler { * SUCCESS if successful, * UNKNOWN_ERROR if failed for other reasons. */ - close() generates (Result result); + close() generates (Result result); }; diff --git a/tv/tuner/1.0/ITuner.hal b/tv/tuner/1.0/ITuner.hal index 61a9d63205..a0f3e8e7d1 100644 --- a/tv/tuner/1.0/ITuner.hal +++ b/tv/tuner/1.0/ITuner.hal @@ -42,6 +42,7 @@ interface ITuner { * * It is used by the client to create a frontend instance. * + * @param frontendId the id of the frontend to be opened. * @return result Result status of the operation. * SUCCESS if successful, * UNKNOWN_ERROR if creation failed for other reasons. diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal index 3fa9641169..4522db24d9 100644 --- a/tv/tuner/1.0/types.hal +++ b/tv/tuner/1.0/types.hal @@ -170,7 +170,7 @@ enum DemuxFilterType : uint32_t { */ VIDEO, /** - * A filter to set PCR channel from input stream. + * A filter to set PCR (Program Clock Reference) channel from input stream. */ PCR, /** @@ -179,11 +179,303 @@ enum DemuxFilterType : uint32_t { RECORD, }; +/* Packet ID is used to specify packets in transport stream. */ +typedef uint16_t DemuxTpid; + +@export +enum Constant : uint16_t { + /** + * An invalid packet ID in transport stream according to ISO/IEC 13818-1. + */ + INVALID_TPID = 0xFFFF, + /** + * An invalid Stream ID. + */ + INVALID_STREAM_ID = 0xFFFF, +}; + +/** + * A status of data in the filter's buffer. + */ +@export +enum DemuxFilterStatus : uint8_t { + /** + * The data in the filter buffer is ready to be read. + */ + DATA_READY = 1 << 0, + /** + * The available data amount in the filter buffer is at low level which is + * set to 25 percent by default. + */ + LOW_WATER = 1 << 1, + /** + * The available data amount in the filter buffer is at high level which is + * set to 75 percent by default. + */ + HIGH_WATER = 1 << 2, + /** + * The data in the filter buffer is full and newly filtered data is being + * discarded. + */ + OVERFLOW = 1 << 3, +}; + +/** + * Bits Setting for Section Filter. + */ +struct DemuxFilterSectionBits { + /* The bytes are configured for Section Filter */ + vec filter; + /* Active bits in the configured bytes to be used for filtering */ + vec mask; + /* + * Do positive match at the bit position of the configured bytes when the + * bit at same position of the mode is 0. + * Do negative match at the bit position of the configured bytes when the + * bit at same position of the mode is 1. + */ + vec mode; +}; + +/** + * Filter Settings for Section data according to ISO/IEC 13818-1. + */ +struct DemuxFilterSectionSettings { + DemuxTpid tpid; + DemuxFilterSectionBits bits; + /* Table ID for Section Filter */ + uint16_t tableId; + /* Version number for Section Filter */ + uint16_t version; + /* true if the filter checks CRC and discards data with wrong CRC */ + bool checkCrc; + /* true if the filter repeats the data with the same version */ + bool isRepeat; + /* true if the filter output raw data */ + bool isRaw; +}; + +/* Stream ID is used to specify one elementary stream */ +typedef uint16_t DemuxStreamId; + +/** + * Filter Settings for a PES Data. + */ +struct DemuxFilterPesDataSettings { + DemuxTpid tpid; + DemuxStreamId streamId; + /* true if the filter output raw data */ + bool bIsRaw; +}; + +/** + * Filter Settings for a TS Data. + */ +struct DemuxFilterTsSettings { + DemuxTpid tpid; +}; + +/** + * Filter Settings for a Audio. + */ +struct DemuxFilterAudioSettings { + DemuxTpid tpid; + /** + * true if the filter output goes to decoder directly in pass through mode. + */ + bool bPassthrough; +}; + +/** + * Filter Settings for a Video. + */ +struct DemuxFilterVideoSettings { + DemuxTpid tpid; + /** + * true if the filter output goes to decoder directly in pass through mode. + */ + bool bPassthrough; +}; + +/** + * Filter Settings for a PCR (Program Clock Reference). + */ +struct DemuxFilterPcrSettings { + DemuxTpid tpid; +}; + +/** + * Indexes can be tagged through TS (Transport Stream) header. + */ +@export +enum DemuxTsIndex : uint32_t { + FIRST_PACKET = 1 << 0, + PAYLOAD_UNIT_START_INDICATOR = 1 << 1, + CHANGE_TO_NOT_SCRAMBLED = 1 << 2, + CHANGE_TO_EVEN_SCRAMBLED = 1 << 3, + CHANGE_TO_ODD_SCRAMBLED = 1 << 4, + DISCONTINUITY_INDICATOR = 1 << 5, + RANDOM_ACCESS_INDICATOR = 1 << 6, + PRIORITY_INDICATOR = 1 << 7, + PCR_FLAG = 1 << 8, + OPCR_FLAG = 1 << 9, + SPLICING_POINT_FLAG = 1 << 10, + PRIVATE_DATA = 1 << 11, + ADAPTATION_EXTENSION_FLAG = 1 << 12, +}; + +/** + * A mask of TS indexes + * + * It's a combination of TS indexes. + */ +typedef bitfield DemuxTsIndexMask; + +/** + * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream) + * according to ISO/IEC 13818-1. + */ +@export +enum DemuxScIndex : uint32_t { + /* Start Code is for a new I Frame */ + I_FRAME = 1 << 0, + /* Start Code is for a new P Frame */ + P_FRAME = 1 << 1, + /* Start Code is for a new B Frame */ + B_FRAME = 1 << 2, + /* Start Code is for a new Sequence */ + SEQUENCE = 1 << 3, +}; + +/** + * A mask of Start Code Indexes + * + * It's a combination of Start Code Indexes. + */ +typedef bitfield DemuxScIndexMask; + +/* Index type to be used in the filter for record */ +@export +enum DemuxRecordIndexType : uint32_t { + /* Don't use index */ + NONE, + /* Use TS index */ + TS, + /* Use Start Code index */ + SC, +}; + +/** + * Filter Settings for Record data. + */ +struct DemuxFilterRecordSettings { + DemuxTpid tpid; + DemuxRecordIndexType indexType; + safe_union IndexMask { + DemuxTsIndexMask tsIndexMask; + DemuxScIndexMask scIndexMask; + } indexMask; +}; + +/** + * Filter Settings. + */ +safe_union DemuxFilterSettings { + DemuxFilterSectionSettings section; + DemuxFilterPesDataSettings pesData; + DemuxFilterTsSettings ts; + DemuxFilterAudioSettings audio; + DemuxFilterVideoSettings video; + DemuxFilterPcrSettings pcr; + DemuxFilterRecordSettings record; +}; + +/** + * The bits of EventFlag in FMQ (Fast message queue) are used by client to + * notify HAL the status change. + */ +@export +enum DemuxQueueNotifyBits : uint32_t { + /* client writes data and notify HAL the data is ready. */ + DATA_READY = 1 << 0, + /* client reads data and notify HAL the data is consumed. */ + DATA_CONSUMED = 1 << 1 +}; + +/** + * Filter Event for Section Filter. + */ +struct DemuxFilterSectionEvent { + /* Table ID of filtered data */ + uint16_t tableId; + /* Version number of filtered data */ + uint16_t version; + /* Section number of filtered data */ + uint16_t sectionNum; + /* Data size in bytes of filtered data */ + uint16_t dataLength; +}; + +/** + * Filter Event for Audio or Video Filter. + */ +struct DemuxFilterMediaEvent { + /* Presentation Time Stamp for audio or video frame. It based on 90KHz has + * the same format as PTS (Presentation Time Stamp). + */ + uint64_t pts; + /* Data size in bytes of audio or video frame */ + uint16_t dataLength; + /* A handle associated to the memory where audio or video data stays. */ + handle secureMemory; +}; + +/** + * Filter Event for PES data. + */ +struct DemuxFilterPesEvent { + DemuxStreamId streamId; + /* Data size in bytes of PES data */ + uint16_t dataLength; +}; + +/** + * Filter Event for Record data. + */ +struct DemuxFilterRecordEvent { + DemuxTpid tpid; + /* Indexes of record output */ + safe_union IndexMask { + DemuxTsIndexMask tsIndexMask; + DemuxScIndexMask scIndexMask; + } indexMask; + /* Packet number from beginning of the filter's output */ + uint64_t packetNum; +}; + /** * Filter Event. */ struct DemuxFilterEvent { - DemuxFilterId filterId; - DemuxFilterType filterType; + DemuxFilterId filterId; + DemuxFilterType filterType; + safe_union Event { + DemuxFilterSectionEvent section; + DemuxFilterMediaEvent media; + DemuxFilterPesEvent pes; + DemuxFilterRecordEvent ts; + }; + /* An array of events */ + vec events; }; +/** + * A hardware resource ID to be used for audio and video hardware sync. + */ +typedef uint32_t AvSyncHwId; + +/** + * A token to be used to link descrambler and key slot. It's opaque to + * framework and apps. + */ +typedef vec TunerKeyToken;