/*
 *        Confidential Information - Limited distribution to authorized persons
 *        only. This material is protected under international copyright laws as
 *        an unpublished work. Do not copy.
 *        Copyright (C) 2010-2011 Dolby Laboratories Inc.
 *        Copyright (C) 2010-2011 Dolby International AB
 *        All rights reserved.
 */

/*! \addtogroup msd */

/*! \file ms_exec.h
 *  \brief Multistream Decoder executive code - header file.
 *
 *   Shows how to initialize and drive the signal processing chain of a
 *   multistream decoder implementation.
 */

/*! \mainpage Multistream Decoder

    This documentation describes the reference source code of the components and subcomponents of the MS11 Multistream Decoder.
    The source code uses the \ref dlb_intrinsics_lib.

    The Dolby&reg; MS11 Multistream Decoder includes three internal components to handle
    decoding, transcoding, and conversion of audio input, depending on the format of the
    audio input and whether the decoder is performing single or dual decoding:
 \li \ref pulse
 \li \ref ddc
 \li \ref ddre

 \note In many use cases, several internal and external components work together to produce final Dolby MS11 Multistream Decoder output.

    The following figure shows the major internal and external components and illustrates the conceptual division of the
    process into a decoding phase, in which PCM is created from the input formats, and an
    encoding phase, in which Dolby Digital output is created.

 \image html ms11_components.png "Dolby MS11 Multistream Decoder Internal and External Components"

 \note Dolby Volume 258 is not part of the MS11 Multistream Decoder source code package.

    Within an Implementation, different configurations can utilize different internal
    components together to provide a supported functionality (for example, dual decoding
    of Dolby Digital Plus). Components produce output that is intended for other internal or
    external components (intermediate outputs) and final Implementation output for use by
    the product that contains the Implementation (system outputs). In some cases,
    component outputs may be ignored when the Implementation output is generated by
    another component.


	  Browse through this documentation by using the navigation pane on the left. A good starting point is "Modules", where the documentation of specific subcomponents (for example, the Back End Encode for the DDC or the Dolby Pulse Transport API) can be found.

    The page below provides an explanation of pre-processor definitions that exist within the code-base.

    \li \subpage define_documentation
*/

/*!
    \page define_documentation List of Pre-Processor Defines

    \note Please be aware that most of the define switches have only been tested thoroughly with their default setting.

    \section def_common Common Pre-Processor Defines

    \li \b DEBUG Activates debug functionality and additional printouts. Set in Makefile.
    \li \b NDEBUG No debug, asserts have no effect. Defined if DEBUG is not defined
    \li \b DOLBY_VOLUME_LIBRARY The Dolby Volume 258 example integration code is under this define. DV258 library needs to be linked against the MS11 source code if the define is set in order to compile. Not defined per default.
    \li \b MS_PRINT_PROCESSING_TIME Processing time is measured with the time command. Defined per default.

    \section def_ddc DDC specific Pre-Processor Defines

    \li \b TC_SUPPORT Enables ability to skip over timecode data prepended to frames if present. Defined per default.
    \li \b KAWARE Enables karaoke-aware features as defined in Annex C of the Dolby Digital specification. Defined per default.
    \li \b KCAPABLE Enables karaoke-capable features as defined in Annex C of the Dolby Digital specification. Dependency: KAWARE defined
    \li \b ARGCHK Enables automatic argument checking at the beginning of each subroutine function. Defined per default.
    \li \b DEV_SINGLEPASSFED Enables the front-end decode (FED) module to run without needing a preliminary \em unpacking pass through prior to the \em decoding pass. Not defined per default.
    \li \b ERRMSG Enables error reporting to standard error output.
    \li \b BAP_REUSE Reuse BAP values in case exponents are shared across blocks
    \li \b DEBUG_NOMAINARGS Enables file based command line options.
    \li \b FIO_MAXPCMCHANS Maximum number of PCM channels for the FIO module
    \li \b MNT_IN_BE_HIGH Store 16 bit mantissa in HIGH word of 32 bit storage.
    \li \b NO_PSD_OVERLAY Save mips using an extra psd buffer.
    \li \b LEGACY_IMDCT Activates the DCT4 implementation used in former releases of the Dolby Digital Plus decoder. Undefined per default.
    \li \b _X86_OPT_ and \b _USING_X86_SSE_ reduce the CPU cycles for Intel X86 type processors. Undefined per default.

    \section def_ddt DDT specific Pre-Processor Defines

    \li \b DEBUG_TOOLS Activate Dolby Pulse related debug printouts depending on debug levels including a command line switch.
    \li \b ALIGN_DEC_OUT Specifies an alignment of the decoder's PCM output to a multiple of ALIGN_DEC_OUT bytes. Not defined per default.
    \li \b CHAR16BIT Platform specific code for compilers with 16bit wide character data type. Only partially working, may be used as an example. Not defined per default.
    \li \b PRINT_TIME_INFO Switches debug infos on in the DDT frontend. Not defined per default.
    \li \b FILENAME_MAX Defines the maximum length of filenames, set in the code. Affects memory needed for storing strings in DDT and DDRE example frontend.
    \li \b MP4_USE_FLOAT Activates float data type usage in the MP4 File Reader. Not defined per default.

    \section def_ddce DD Encoder specific Pre-Processor Defines

    \li \b DD_OPTIMIZED_QUANTIZATION Bit-exact performance optimization, needs more memory. Defined per default.
    \li \b DOUBLE_BAP During bit allocation, the snr offset of the last known good bit allocation is kept.  At the end of bit allocation, the last known good snr offset is run once more, to fill the bap buffers with the proper information for mantissa quantization. If this is defined, during bit allocation the last known good set of bit allocation parameters is kept.  This obviates the need for that final bit allocation run, thus saving MIPs (but costing RAM). Defined in source code.
    \li \b REDUCED_PRECISION_BIQUAD Biquad filter with 16bit coeffs, not bitexact, but test passes if coupling mode is off. Defined per default.
    \li \b REDUCED_PRECISION_DD_WINDOW 16bit MDCT window. Defined per default.

    \section def_notsettable Pre-Processor Defines not settable by the user

    \li \b DDCE_V3_2_1 Encapsulates encoder features which are not used in MS11, large parts of this define have already been stripped from the code.
    \li \b DLB_METHOD_IS_FLOAT Is set automatically if a floating point backend is used.
    \li \b MAX_FRAME_SIZE Dolby Pulse decoder frame size, automatically set depending on compiled in decoder features (SBR, MPS etc).
    \li \b MAX_COLS Max. number of QMF time slots per frame. Automatically set, depends on MAX_FRAME_SIZE define.
    \li \b USFRACT Macro, which converts a float argument to an unsigned int16 type.
    \li \b NULL Sets NULL to 0L if not defined already by compiler.
    \li \b EOF Sets EOF to -1 if not set already by compiler.
    \li \b TEXT 	Macro for handling text based error messages in mp4ffSimpleReader.
    \li \b DLB_LFRACT_BITS Number of bits for LFRACT data type, set automatically in the intrinsics.
    \li \b DLB_SFRACT_BITS Number of bits for SFRACT data type, set automatically in the intrinsics.
    \li \b _CRT_SECURE_NO_DEPRECATE Visual Studio flag to disable deprecation of functions such as sprintf, strcpy, etc.
    \li \b _MSC_VER Compiler defined macro, automatically defined if building under any Visual C++ toolchain.
*/

#ifndef MS_EXEC_H_
#define MS_EXEC_H_

#include "dolbypulsedecodertranscoder.h"
#include "dolbydigitalreencoder.h"

#include "gbl.h"     /* bfd.h depends on it */
#include "err.h"     /* bfd.h depends on it */
#include "bfd.h"     /* ddc_api.h depends on it */
#include "ddc_api.h"

#include "callback.h"
#include "callback_258.h"

#define MS_PRINT_PROCESSING_TIME

#ifdef MS_PRINT_PROCESSING_TIME
#include <time.h>
#endif

#define MS_MAJOR_VERSION      "2"
#define MS_MINOR_VERSION      "0"
#define MS_UPDATE_VERSION     "0"
#define MS_COPYRIGHT          gbl_dolby_copyright


/*! Channel Reordering table from cinema order to WAVE channel order */

typedef struct MS_RUNTIME_PARAMS MS_RUNTIME_PARAMS;
typedef struct MS_INIT_PARAMS MS_INIT_PARAMS;
typedef struct MS_PARAMS MS_PARAMS;
typedef struct MS_IOBUFFER MS_IOBUFFER;

typedef void* HANDLE_DUAL_DECODER_CONVERTER;

/* Determines the indices of the two DDT instances and thus which one will be decoded first */
#define MS_DDT_MAIN_INSTANCE        0
#define MS_DDT_ASSOC_INSTANCE       1

#define MS_DOWNMIX_OUT              0
#define MS_VIRTUALIZER_OUT          1
#define MS_ASSOC_DOWNMIX_OUT        MS_VIRTUALIZER_OUT
#define MS_MIXER_OUT                2

#define MS_MAIN_OUT                 0
#define MS_ASSOC_OUT                1

#define IDK_TESTMODE_DECODER_OUTPUT 1
#define IDK_TESTMODE_DD_ENC         2

#define AUTO_FORMAT                 0
#define ADTS_FORMAT                 1
#define LOAS_FORMAT                 2
#define RAW_FORMAT                  3

#define DDRE_FS_OUT             48000

#define MS_MAX_STR_LEN            256

#define MS_MAX_EXTPCM_CH            6
#define MS_EXTPCM_IN_SAMPLES     1536

const GBL_CH_ID ms_cinema2wav_chanorder_tab[] = {GBL_LEFT, GBL_RGHT, GBL_CNTR, GBL_RSUR, GBL_LFE, GBL_LSUR};

static const int ms_downmix_idx[] = {MS_DOWNMIX_OUT, MS_ASSOC_DOWNMIX_OUT};
typedef enum MS_RETVAL{MS_OK=0, MS_GENERAL_ERROR, MS_OUT_OF_MEMORY, MS_READ_ERROR, MS_OPEN_FILE_ERROR, MS_FILE_IO_ERROR,
                       MS_ERR_INCOMPLETE_FRAME_READ, MS_ERR_ALL_INBUFS_LOCKED, MS_INVALID_BFD, MS_HELPTEXT_REQUESTED,
                       MS_INVALID_PARAM, MS_PROCESS_ERROR, MS_SET_PARAM_ERROR, MS_ERR_ENC_TESTMODE} MS_RETVAL;

/*! Enumeration of possible input types beeing processed by the multistream decoder */
typedef enum MS_INPUT_TYPE { DOLBY_DIGITAL_PLUS, DOLBY_PULSE, EXTERNAL_PCM } MS_INPUT_TYPE;

/*! Struct defining the current use case, not all permutations are allowed */
typedef struct MS_USE_CASE{
  MS_INPUT_TYPE    input_type; /*!< Either Dolby Pulse, Dolby Digital Plus or external PCM */
  int          b_dolby_volume; /*!< Flag indicating if Dolby Volume 258 is enabled */
  int             b_ms10_mode; /*!< Flag indicating that processing is restriced to MS10 features */
  int            b_dual_input; /*!< Flag indicating if two input streams are present (n/a for external PCM) */
  int         b_file_playback; /*!< Flag indicating file playback (Dolby Pulse with single input only) */
  int         b_restricted_ad; /*!< Flag indicating that the associated instance is restricted to 2 channels (Dolby Pulse only) */
  int              b_mainonly; /*!< Flag indicating that the DDC shall handle only the main program */
  int            idk_testmode; /*!< IDK testmode, 0: regular processing, 1: decoder output */
  uint32_t       main_channels;
  uint32_t       assoc_channels;
  uint32_t       pcm_channels;
  uint32_t       main_samp_rate;
  uint32_t       assoc_samp_rate;
  uint32_t       pcm_samp_rate;
} MS_USE_CASE;

/*! Struct holding the memory sizes needed for the current use case */
typedef struct MS_MEM_SIZES{
  uint32_t intern_static_size;  /*!< Required memory size for internal (fast) static memory */
  uint32_t intern_dynamic_size; /*!< Required memory size for dynamic memory (scratch) */
  uint32_t extern_static_size;  /*!< Required memory size for external (slow) static memory */
} MS_MEM_SIZES;

/*! Struct holding the pointer to the different memory types */
typedef struct MS_MEM_PTR{
  uint32_t *p_intern_static;  /*!< Pointer to the internal (fast) static memory */
  uint32_t *p_intern_dynamic; /*!< Pointer to the internal dynamic memory (scratch) */
  uint32_t *p_extern_static;  /*!< Pointer to the external (slow) static memory */
} MS_MEM_PTR;

/*! Struct containing all handles to the top level components available */
typedef struct MS_COMPONENTS_HANDLE{
  HANDLE_DOLBY_PULSE_DECODER_TRANSCODER p_handle_ddt[2]; /*!< Handles of main and associated DDT instance */
  HANDLE_DOLBY_DIGITAL_REENCODER handle_ddre;            /*!< Handle of the DDRE instance */
  HANDLE_DUAL_DECODER_CONVERTER handle_ddc;              /*!< Handle of the DDC instance */
  MS_MIXER_HANDLE handle_ms_mixer;                       /*!< Handle to the MS Mixer */
  DV_258_DATA dv258_data;                                /*!< Handle to the DV258 static data */
  MIXER_INSTANCE mixer_data;                             /*!< Data for the mixer callback */
  MS_MEM_PTR ddre_mem_ptr;                               /*!< Memory Pointer for reopening the DDRE handle */

#ifdef DOLBY_VOLUME_LIBRARY
  ak_memory_pool  *dv_pool[2];                           /*!< Pointer to the memory pools for the two DV-258 instances */
  void*           *dv_pmem[2];                           /*!< Pointer to the Program Memory for the two DV-258 instances */
#endif
} MS_COMPONENTS_HANDLE;



/*! Struct containing the state variables for the multistream decoder processing */
typedef struct MS_PROCESSING_STATE{
  int       b_end_processing;                   /*!< Indicates to end the processing loop right away */
  int       b_end_processing_after_process;     /*!< Indicates to end the processing loop after ms_process() */
  uint32_t  frame_ctr;                          /*!< Counts the number of written output frames */
  int       verbosity;                          /*!< Determines the amount of printouts */

  /* DDT specific variables */
  int       p_ddt_status[2];                    /*!< Return Value of the two ddt instances */
  int       p_dpulse_start_offset[2];           /*!< Dolby Pulse input buffer start offset (main and assoc.) */
  int       p_dpulse_end_offset[2];             /*!< Dolby Pulse input buffer end offset (main and assoc.) */
  int       dpulse_flushing;                    /*!< Indicates that the decoder shall flush its remaining internal PCM samples */
  int       p_dpulse_input_eof[2];              /*!< End of file indication for main and associate */
  int       dpulse_missing_output_cnt;          /*!< Counts the number of frames without output beeing generated */
  int       p_dpulse_id_cnt[2];            /*!< Counts the number of Pulse IDs found (main and assoc.) */

  /* DDRE specific variables */
  int       ddre_status;                        /*!< Return value of the DDRE */
  int       b_ddre_reopened;                    /*!< Indicates that the DDRE has been reopened */


  /* IDK test specific */
  int       channels;                           /*!< Number of channels in the output buffer for IDK testpoints */
  TRANSCODER_CHANNEL_CONFIG prev_6ch_config;    /*!< Channel configuration of virtualizer output in the last frame */
  int16_t   p_prev_delay[2];                    /*!< PCM input/output delay of last frame */
  int16_t   prev_2ch_dsurmod;                   /*!< PCM downmix dsurmod of last frame */
  uint32_t  prev_pcm_fs;                        /*!< Sampling rate of PCM output in the last frame */

  uint32_t  sampling_rate_in;                   /*!< Sampling rate of the input */
  uint32_t  sampling_rate_out;                  /*!< Output PCM sampling rate */
  uint16_t  p_in_bytes_read[2];                 /*!< Number of bytes consumed from the input buffer (one for each instances) */
  uint16_t  p_in_buf_len[2];                    /*!< Number of bytes in the input buffer (one for each instance) */
  int16_t   samples_consumed;                   /*!< Number of PCM samples consumed from the input buffer (DDRE) */
  uint16_t  bytes_written;                      /*!< Number of bytes written in the DD output buffer */

  uint16_t  stereo_dsurmod;                     /*!< Indicates if 2 channel output is Dolby Surround encoded */
  TRANSCODER_CHANNEL_CONFIG ch_config_6ch_out;  /*!< Indicates the output channel configuration of the 6 channel output */
  DLB_SFRACT *pp_ddre_input[DDPI_DDC_MAXPCMOUTCHANS]; /*!< Pointer array to the DDRE input channels */

  /* DDC specific */
  DDPI_DDC_PT_OP   ddc_process_timeslice_outparams; /*!< Output parameters of the timeslice processing function */
  GBL_REENCDATA    reencdata;                       /*!< Meta data for reencoding */
  GBL_MIXDATA      mixdata;                         /*!< Meta data for mixing */
  int16_t          skip_ddc_processing;             /*!< Indicates when DD(+) decoding should be skipped because enough samples
                                                         are available at the DDRE */
  int16_t          ddplus_prev_substreams;          /*!< Available substreams of previous frame */

} MS_PROCESSING_STATE;

/*!
 * \brief This function returns the memory demand for the specified use case. The sizes are given for the worst case scenario.
 *
 * The function queries the memory sizes of all components that are potentialy needed for the current use case and returns
 * the total amount in bytes. There are three different memory types that can be requested by the multistream decoder. Internal
 * dynamic memory is scratch memory that can be overwritten after the call to the ms_process() function. External and internal
 * static memory needs to persist in between calls. The only difference is how fast the memory can be accessed, e.g. internal
 * static memory would be mapped to local on-chip memory while external memory would be mapped to external RAM memory.
 *
 * \return MS_OK on success
 */
//MS_RETVAL ms_query_memory(MS_USE_CASE  *p_use_case,   /*!< [in] Defines the current use case */
//                          MS_MEM_SIZES *p_mem_sizes   /*!< [out] Structure holding the memory sizes */
//                          );
/*!
 * \brief This function allocates the required memory sizes
 *
 * Memory blocks for internal dynamic as well as internal and external static memory are allocated.
 *
 * \return MS_OK on success
 */
//MS_RETVAL ms_allocate_memory(MS_MEM_SIZES *p_mem_sizes, /*!< [in] Structure holding the memory sizes */
//                             MS_MEM_PTR *p_mem_ptr      /*!< [out] Pointer to the allocated memory */
//                             );

/*! This function assigns memory blocks to the component handles required in the current use case.
 *  The components are initialized with the use case default values.
 */
//MS_RETVAL ms_open_components(MS_MEM_PTR *p_mem_ptr,               /*!< [in] Pointer to the allocated memory */
//                             MS_USE_CASE *p_use_case,             /*!< [in] Defines the current use case */
//                             MS_INIT_PARAMS *p_init_params,       /*!< [in] Struct holding parameters set at init time */
//                             MS_COMPONENTS_HANDLE *p_comp_handles /*!< [out] Component Handles with pointers
//                                                                    assigned to memory blocks */
//                             );

/*! \brief This function sets all runtime parameters */
//MS_RETVAL ms_set_process_params(MS_USE_CASE *p_use_case,             /*!< [in] Defines the current use case */
//                                MS_RUNTIME_PARAMS *p_runtime_args,   /*!< [in] Runtime depending parameters */
//                                MS_COMPONENTS_HANDLE *p_comp_handles /*!< [in,out] Component handles
//                                                                       needed for setting parameter */
//                                );
/*!
 * \brief This function implements the actual call to the appropiate process functions of the components
 * that are needed in the current use case.
 */
//MS_RETVAL ms_process(MS_USE_CASE *p_use_case,             /*!< [in] Defines the current use case */
//                     MS_RUNTIME_PARAMS *p_runtime_args,   /*!< [in] Runtime depending parameters */
//                     MS_PROCESSING_STATE *p_proc_state,   /*!< [in,out] State variables for the processing loop */
//                     MS_COMPONENTS_HANDLE *p_comp_handles,/*!< [in,out] Component handles needed for setting parameter */
//                     MS_IOBUFFER *p_iobuffer              /*!< [in,out] Struct containing all io buffer related information */
//                     );


/*! \brief Frees up the allocated memory of all components */
//MS_RETVAL ms_free_memory(MS_MEM_PTR *p_mem_ptr      /*!< [in, out] Pointer to the allocated memory */
//                         );



#endif /* MS_EXEC_H_ */
