From 8e087bf394c5ceddcdb8b1d029795aff3026eea0 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 20 May 2014 17:29:03 -0700 Subject: [PATCH] AAC-Decoder: DRC metadata in stream info Provide relevant DRC metadata information via API needed for DRC presentation mode wrapper. Bug 9428126 Change-Id: I827cd6bdfd2a8799c21935ae32af23739c90a9b6 --- libAACdec/include/aacdecoder_lib.h | 24 +++++++++++++++++----- libAACdec/src/aacdec_drc.cpp | 32 +++++++++++++++++++++++++++++- libAACdec/src/aacdec_drc.h | 12 +++++++++++ libAACdec/src/aacdec_drc_types.h | 3 +++ libAACdec/src/aacdecoder.cpp | 11 ++++++++++ libAACdec/src/aacdecoder_lib.cpp | 2 +- 6 files changed, 77 insertions(+), 7 deletions(-) diff --git a/libAACdec/include/aacdecoder_lib.h b/libAACdec/include/aacdecoder_lib.h index bf6dcfb..a0c0854 100644 --- a/libAACdec/include/aacdecoder_lib.h +++ b/libAACdec/include/aacdecoder_lib.h @@ -144,10 +144,9 @@ to allocate memory for the required structures, and the corresponding mpegFileRe files and to de-allocate associated structures. mpegFileRead_Open() tries to detect the bitstream format and in case of MPEG-4 file format or Raw Packets file format (a Fraunhofer IIS proprietary format) reads the Audio Specific Config data (ASC). An unsuccessful attempt to recognize the bitstream format requires the user to -provide this information manually (see \ref CommandLineUsage). For any other bitstream formats that are -usually applicable in streaming applications, the decoder itself will try to synchronize and parse the given -bitstream fragment using the FDK transport library. Hence, for streaming applications (without file access) -this step is not necessary. +provide this information manually. For any other bitstream formats that are usually applicable in streaming +applications, the decoder itself will try to synchronize and parse the given bitstream fragment using the +FDK transport library. Hence, for streaming applications (without file access) this step is not necessary. -# Call aacDecoder_Open() to open and retrieve a handle to a new AAC decoder instance. \dontinclude main.cpp @@ -571,10 +570,25 @@ typedef struct UINT numTotalAccessUnits; /*!< This is the number of total access units that have passed through the decoder. */ UINT numBadAccessUnits; /*!< This is the number of total access units that were considered with errors from numTotalBytes. */ + /* Metadata */ + SCHAR drcProgRefLev; /*!< DRC program reference level. Defines the reference level below full-scale. + It is quantized in steps of 0.25dB. The valid values range from 0 (0 dBFS) to 127 (-31.75 dBFS). + It is used to reflect the average loudness of the audio in LKFS accoring to ITU-R BS 1770. + If no level has been found in the bitstream the value is -1. */ + SCHAR drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154, this field indicates whether + light (MPEG-4 Dynamic Range Control tool) or heavy compression (DVB heavy compression) + dynamic range control shall take priority on the outputs. + For details, see ETSI TS 101 154, table C.33. Possible values are: \n + -1: No corresponding metadata found in the bitstream \n + 0: DRC presentation mode not indicated \n + 1: DRC presentation mode 1 \n + 2: DRC presentation mode 2 \n + 3: Reserved */ + } CStreamInfo; -typedef struct AAC_DECODER_INSTANCE *HANDLE_AACDECODER; +typedef struct AAC_DECODER_INSTANCE *HANDLE_AACDECODER; /*!< Pointer to a AAC decoder instance. */ #ifdef __cplusplus extern "C" diff --git a/libAACdec/src/aacdec_drc.cpp b/libAACdec/src/aacdec_drc.cpp index ba7419d..0c33a2b 100644 --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -145,6 +145,8 @@ void aacDecoder_drcInit ( /* initial program ref level = target ref level */ self->progRefLevel = pParams->targetRefLevel; + self->progRefLevelPresent = 0; + self->presMode = -1; } @@ -572,7 +574,7 @@ static int aacDecoder_drcReadCompression ( return 0; } FDKreadBits(bs, 2); /* dolby_surround_mode */ - FDKreadBits(bs, 2); /* presentation_mode */ + pDrcBs->presMode = FDKreadBits(bs, 2); /* presentation_mode */ FDKreadBits(bs, 1); /* stereo_downmix_mode */ if (FDKreadBits(bs, 1) != 0) { /* reserved, set to 0 */ return 0; @@ -803,9 +805,15 @@ static int aacDecoder_drcExtractAndMap ( */ if (pThreadBs->progRefLevel >= 0) { self->progRefLevel = pThreadBs->progRefLevel; + self->progRefLevelPresent = 1; self->prlExpiryCount = 0; /* Got a new value -> Reset counter */ } + if (drcPayloadType == DVB_DRC_ANC_DATA) { + /* Announce the presentation mode of this valid thread. */ + self->presMode = pThreadBs->presMode; + } + /* SCE, CPE and LFE */ for (ch = 0; ch < validChannels; ch++) { int mapedChannel = channelMapping[ch]; @@ -825,6 +833,7 @@ static int aacDecoder_drcExtractAndMap ( if ( (pParams->expiryFrame > 0) && (self->prlExpiryCount++ > pParams->expiryFrame) ) { /* The program reference level is too old, so set it back to the target level. */ + self->progRefLevelPresent = 0; self->progRefLevel = pParams->targetRefLevel; self->prlExpiryCount = 0; } @@ -1156,3 +1165,24 @@ int aacDecoder_drcEpilog ( return err; } +/* + * Export relevant metadata info from bitstream payload. + */ +void aacDecoder_drcGetInfo ( + HANDLE_AAC_DRC self, + SCHAR *pPresMode, + SCHAR *pProgRefLevel ) +{ + if (self != NULL) { + if (pPresMode != NULL) { + *pPresMode = self->presMode; + } + if (pProgRefLevel != NULL) { + if (self->progRefLevelPresent) { + *pProgRefLevel = self->progRefLevel; + } else { + *pProgRefLevel = -1; + } + } + } +} diff --git a/libAACdec/src/aacdec_drc.h b/libAACdec/src/aacdec_drc.h index 41aac69..c850aa5 100644 --- a/libAACdec/src/aacdec_drc.h +++ b/libAACdec/src/aacdec_drc.h @@ -173,5 +173,17 @@ int aacDecoder_drcEpilog ( UCHAR channelMapping[], int validChannels ); +/** + * \brief Get metadata information found in bitstream. + * \param self DRC module instance handle. + * \param pPresMode Pointer to field where the presentation mode will be written to. + * \param pProgRefLevel Pointer to field where the program reference level will be written to. + * \return Nothing. + */ +void aacDecoder_drcGetInfo ( + HANDLE_AAC_DRC self, + SCHAR *pPresMode, + SCHAR *pProgRefLevel ); + #endif /* AACDEC_DRC_H */ diff --git a/libAACdec/src/aacdec_drc_types.h b/libAACdec/src/aacdec_drc_types.h index 1f595b9..4c6d163 100644 --- a/libAACdec/src/aacdec_drc_types.h +++ b/libAACdec/src/aacdec_drc_types.h @@ -124,6 +124,7 @@ typedef struct { UINT excludedChnsMask; SCHAR progRefLevel; + SCHAR presMode; /* Presentation mode: 0 (not indicated), 1, 2, and 3 (reserved). */ SCHAR pceInstanceTag; CDrcChannelData channelData; @@ -156,9 +157,11 @@ typedef struct USHORT numPayloads; /* The number of DRC data payload elements found within frame */ USHORT numThreads; /* The number of DRC data threads extracted from the found payload elements */ SCHAR progRefLevel; /* Program reference level for all channels */ + UCHAR progRefLevelPresent; /* Program reference level found in bitstream */ UINT prlExpiryCount; /* Counter that can be used to monitor the life time of the program reference level. */ + SCHAR presMode; /* Presentation mode as defined in ETSI TS 101 154 */ UCHAR dvbAncDataAvailable; /* Flag that indicates whether DVB ancillary data is present or not */ UINT dvbAncDataPosition; /* Used to store the DVB ancillary data payload position in the bitstream (only one per frame) */ UINT drcPayloadPosition[MAX_DRC_THREADS]; /* Used to store the DRC payload positions in the bitstream */ diff --git a/libAACdec/src/aacdecoder.cpp b/libAACdec/src/aacdecoder.cpp index 15b47ab..e19c501 100644 --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -719,6 +719,10 @@ void CStreamInfoInit(CStreamInfo *pStreamInfo) pStreamInfo->frameSize = 0; pStreamInfo->outputDelay = 0; + + /* DRC */ + pStreamInfo->drcProgRefLev = -1; /* set program reference level to not indicated */ + pStreamInfo->drcPresMode = -1; /* default: presentation mode not indicated */ } /*! @@ -1785,6 +1789,13 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecoder_DecodeFrame( /* Add additional concealment delay */ self->streamInfo.outputDelay += CConcealment_GetDelay(&self->concealCommonData) * self->streamInfo.aacSamplesPerFrame; + /* Map DRC data to StreamInfo structure */ + aacDecoder_drcGetInfo ( + self->hDrcInfo, + &self->streamInfo.drcPresMode, + &self->streamInfo.drcProgRefLev + ); + /* Reorder channel type information tables. */ { AUDIO_CHANNEL_TYPE types[(8)]; diff --git a/libAACdec/src/aacdecoder_lib.cpp b/libAACdec/src/aacdecoder_lib.cpp index e2c757a..8e3027a 100644 --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -110,7 +110,7 @@ amm-info@iis.fraunhofer.de /* Decoder library info */ #define AACDECODER_LIB_VL0 2 #define AACDECODER_LIB_VL1 5 -#define AACDECODER_LIB_VL2 8 +#define AACDECODER_LIB_VL2 9 #define AACDECODER_LIB_TITLE "AAC Decoder Lib" #define AACDECODER_LIB_BUILD_DATE __DATE__ #define AACDECODER_LIB_BUILD_TIME __TIME__