text: #ifndef AUDIO_DECODER_H
  #define AUDIO_DECODER_H
  
  #include "generic/typedef.h"
  #include "generic/list.h"
  #include "media/audio_base.h"
  #include "media/audio_stream.h"
  #include "os/os_api.h"
  
  
  
  // 解码事件
  enum {
      AUDIO_DEC_EVENT_CURR_TIME = 0x20,
      AUDIO_DEC_EVENT_END,
      AUDIO_DEC_EVENT_ERR,
      AUDIO_DEC_EVENT_SUSPEND,
      AUDIO_DEC_EVENT_RESUME,
      AUDIO_DEC_EVENT_START,
  };
  
  // 资源回调事件
  enum {
      AUDIO_RES_GET,
      AUDIO_RES_PUT,
  };
  
  // 解码状态
  enum {
      DEC_STA_TRY_START,
      DEC_STA_START,
      DEC_STA_WAIT_STOP,
      DEC_STA_WAIT_SUSPEND,
      DEC_STA_WAIT_RESUME,
      DEC_STA_WAIT_PAUSE,
  };
  
  // AB点复读模式
  enum {
      AB_REPEAT_MODE_BP_A = 0x01,
      AB_REPEAT_MODE_BP_B,
      AB_REPEAT_MODE_CUR,
  };
  
  // 解码器命令
  enum {
      AUDIO_IOCTRL_CMD_SET_BREAKPOINT_A = 0x08,	// 设置复读A点
      AUDIO_IOCTRL_CMD_SET_BREAKPOINT_B,			// 设置复读B点
      AUDIO_IOCTRL_CMD_SET_BREAKPOINT_MODE,		// 设置AB点复读模式
  
      AUDIO_IOCTRL_CMD_REPEAT_PLAY = 0x90,		// 设置循环播放
      AUDIO_IOCTRL_CMD_SET_DEST_PLAYPOS = 0x93,	// 设置指定位置播放
      AUDIO_IOCTRL_CMD_GET_PLAYPOS = 0x94,		// 获取毫秒级时间
  };
  
  /*
   * 指定位置播放
   * 设置后跳到start_time开始播放，
   * 播放到dest_time后如果callback_func存在，则调用callback_func，
   * 可以在callback_func回调中实现对应需要的动作
   */
  struct audio_dest_time_play_param {
      u32 start_time;	// 要跳转过去播放的起始时间。单位：ms
      u32 dest_time;	// 要跳转过去播放的目标时间。单位：ms
      u32(*callback_func)(void *priv);	// 到达目标时间后回调
      void *callback_priv;	// 回调参数
  };
  
  /*
   * 获取毫秒级解码时间
   */
  struct audio_get_play_ms_time_param {
      u32 time_ms;
  };
  
  /*
   * ab点复读模式结构体
   */
  struct audio_ab_repeat_mode_param {
      u32 value;
  };
  
  /*
   * 循环播放fifo
   */
  struct fixphase_repair_obj {
      short fifo_buf[18 + 12][32][2];
  };
  
  /*
   * 循环播放结构体
   * 每次播放会根据headcut_frame和tailcut_frame来砍掉一些不需要的帧
   * 在repeat_callback()回调中可以自主控制播放次数，返回非0即结束循环
   */
  struct audio_repeat_mode_param {
      int flag;
      int headcut_frame;	// 砍掉前面几帧，仅mp3格式有效
      int tailcut_frame;	// 砍掉后面几帧，仅mp3格式有效
      int (*repeat_callback)(void *);	// 循环播放回调，返回0-正常循环；返回非0-结束循环
      void *callback_priv;
      struct fixphase_repair_obj *repair_buf;
  };
  
  /*
   *解码任务cpu占用率跟踪:
   *跟踪周期trace_period内，如果解码任务空闲时间统计少于
   *期望值(idle_expect),就会触发饱和保护机制。默认是挂起自
   *身pend_time.如果想要自己做处理，只需注册trace_hdl即可
   */
  struct audio_decoder_occupy {
      u8 pend_time;		//挂起时间,os_time_dly(pend_time)
      u16 idle_expect;	//跟踪周期内期望idle时间
      u16 trace_period;	//跟踪周期，单位：ms
      int (*trace_hdl)(void *priv, u32 idle_total); //跟踪回调函数
  };
  
  /*
   * 资源处理结构体
   * res会先挂载到链表中，然后依据以下规律依次执行：
   * protect置1时，马上开始播放（叠加播放），不会结束其他的res
   * preemption置1时，马上开始播放（抢占播放），会结束当前非protect模式的res
   * protect和preemption为0时，依据priority优先级播放
   * 按优先级排序的情况下，由snatch_same_prio决定是否放在同优先级的前面
   * preemption方式和priority优先级方式，同一时刻只会有一个解码
   * preemption方式的全部播放完后才开始播放按priority优先级排序的
   */
  struct audio_res_wait {
      struct list_head list_entry;	// 链表。用于多个解码抢占/排序等
      u8 priority;		// 优先级
      u8 preemption : 1;	// 抢占
      u8 protect : 1;		// 保护（叠加）
      u8 only_del : 1; 	// 仅删除
      u8 snatch_same_prio : 1; // 放在同优先级的前面
      u8 is_work : 1; 	// 已经运行
      u32 format;			// 格式锁
      int (*handler)(struct audio_res_wait *, int event); // 回调
  };
  
  /*
   * 解码任务结构体
   * 链接所有的解码，按list链表循环执行
   */
  struct audio_decoder_task {
      struct list_head head;	// 用于解码任务中的轮询处理
      struct list_head wait;	// 用于多个解码抢占/排序等
      struct audio_decoder_occupy occupy;//
      const char *name;	// 解码任务名称
      int wakeup_timer;	// 定时唤醒
      int fmt_lock;		// 格式锁
      u16 is_add_wait : 1;	// 正在添加res资源
      u16 step_cnt : 8;
      u16 step_timer;
      void *out_task;		// 使用单独任务做输出
  };
  
  
  /*
   * 解码断点结构体
   */
  struct audio_dec_breakpoint {
      int len;
      u32 fptr;
      int data_len;
      u8 data[0];
      // u8 data[128];
  };
  
  struct audio_decoder;
  
  
  /*
   * 解码输入接口
   * 用于获取音频数据，分为音频文件和音频流
   */
  struct audio_dec_input {
      u32 coding_type;
      // 定义在p_more_coding_type数组中的解码器会依照顺序依次检测
      // 先检测coding_type再检测p_more_coding_type
      u32 *p_more_coding_type;
      u32 data_type : 8;
      union {
          struct { // data_type == AUDIO_INPUT_FILE
              int (*fread)(struct audio_decoder *, void *buf, u32 len);
              int (*fseek)(struct audio_decoder *, u32 offset, int seek_mode);
              int (*ftell)(struct audio_decoder *);
              int (*flen)(struct audio_decoder *);
          } file;
  
          struct { // data_type == AUDIO_INPUT_FRAME
              int (*fget)(struct audio_decoder *, u8 **frame);
              void (*fput)(struct audio_decoder *, u8 *frame);
              int (*ffetch)(struct audio_decoder *, u8 **frame);
          } frame;
      } ops;
  };
  
  /*
   * 解码处理过程中的回调
   */
  struct audio_dec_handler {
      int (*dec_probe)(struct audio_decoder *);	// 预处理。返回非0值不跑后续的解码run
      // 解码输出。解码会自动输出到数据流中，上层不必要实现该函数
      int (*dec_output)(struct audio_decoder *, s16 *data, int len, void *priv);
      int (*dec_post)(struct audio_decoder *);	// 后处理
      int (*dec_stop)(struct audio_decoder *);	// 解码结束
  };
  
  /*
   * 数据流解码信息
   */
  struct stream_codec_info {
      int  time;
      int  frame_num;
      u32  frame_len;
      int  frame_points;
      int  sequence_number;
      u32  sample_rate;
      u8   channel;
  };
  
  /*
   * 解码器结构体
   * 所有挂载到解码的解码器都需要该结构体
   * 至少需要实现open/start/run/close等函数
   */
  struct audio_decoder_ops {
      u32 coding_type;
      void *(*open)(void *priv);	// 打开解码器，获取句柄
      int (*start)(void *);		// 启动解码
      int (*get_fmt)(void *, struct audio_fmt *fmt);			// 获取解码信息
      int (*set_output_channel)(void *, enum audio_channel);	// 设置输出声道
      int (*get_play_time)(void *);				// 获取当前解码时间
      int (*fast_forward)(void *, int step_s);	// 快进，step单位：秒
      int (*fast_rewind)(void *, int step_s);		// 快退，step单位：秒
      int (*get_breakpoint)(void *, struct audio_dec_breakpoint *);	// 获取断点信息
      int (*set_breakpoint)(void *, struct audio_dec_breakpoint *);	// 设置断点buf
      int (*stream_info_scan)(void *, struct stream_codec_info *info, void *data, int len);	// 数据流信息检测
      int (*set_tws_mode)(void *, int);			// 设置tws解码模式
      int (*run)(void *, u8 *);					// 运行解码
      int (*stop)(void *);						// 停止解码
      int (*close)(void *);						// 关闭解码，释放空间
      int (*reset)(void *);						// 重启解码
      int (*ioctrl)(void *, u32 cmd, void *parm);	// 解码控制。如设置AB点复读等
  };
  
  #define REGISTER_AUDIO_DECODER(ops) \
          const struct audio_decoder_ops ops SEC(.audio_decoder)
  
  extern const struct audio_decoder_ops audio_decoder_begin[];
  extern const struct audio_decoder_ops audio_decoder_end[];
  
  #define list_for_each_audio_decoder(p) \
      for (p = audio_decoder_begin; p < audio_decoder_end; p++)
  
  
  /*
   * 解码通道
   */
  struct audio_decoder {
      struct list_head list_entry;		// 链表。用于解码任务中轮询处理
      struct audio_decoder_task *task;	// 解码任务
      struct audio_fmt fmt;				// 解码格式
      const char *evt_owner;				// 用于接受消息的任务名称
      const struct audio_dec_input *input;			// 解码输入接口
      const struct audio_decoder_ops *dec_ops;		// 解码器接口
      const struct audio_dec_handler *dec_handler;	// 解码处理回调
      void (*evt_handler)(struct audio_decoder *dec, int, int *);	// 事件回调
      void *dec_priv;		// 解码器对应句柄
      void *bp;			// 断点
      // u16 id;			// ID号
      u16 pick : 1;		// 本地拆包解码标记
      u16 tws : 1;		// 本地tws解码标记
      u16 output_err : 1;	// 解码输出错误
      u16 read_err : 1;	// 解码读取错误
      u16 open_step : 4;
      u8 run_max;			// 正常解码最大次数
      // u8 output_channel;	// 输出通道
      u8 state;			// 解码状态
      u8 err;				// 解码结束错误类型标记
      u8 remain;			// 解码输出完成标记
      volatile u8 resume_flag;// 解码激活标记
      u32 magic;			// 事件回调的私有标记
      u32 process_len;	// 数据流处理长度
      struct audio_stream_entry entry;	// 音频流入口
      void *out_task_ch;	// 使用单独任务做输出
  };
  
  // 解码输出声道类型
  #define AUDIO_DEC_ORIG_CH       AUDIO_CH_LR
  #define AUDIO_DEC_L_CH          AUDIO_CH_L
  #define AUDIO_DEC_R_CH          AUDIO_CH_R
  #define AUDIO_DEC_MONO_LR_CH    AUDIO_CH_DIFF
  #define AUDIO_DEC_DUAL_L_CH     AUDIO_CH_DUAL_L
  #define AUDIO_DEC_DUAL_R_CH     AUDIO_CH_DUAL_R
  #define AUDIO_DEC_DUAL_LR_CH    AUDIO_CH_DUAL_LR
  
  #define AUDIO_DEC_IS_MONO(ch)	(((ch)==AUDIO_DEC_L_CH) || ((ch)==AUDIO_DEC_R_CH) || ((ch)==AUDIO_DEC_MONO_LR_CH))
  
  /*
  *********************************************************************
  *                  Audio Decoder Task Create
  * Description: 创建解码任务
  * Arguments  : *task	任务句柄
  *              *name	任务名
  * Return	 : 0		成功
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_task_create(struct audio_decoder_task *task, const char *name);
  
  /*
  *********************************************************************
  *                  Audio Decoder Task Add ResWait
  * Description: 解码任务增加解码通道资源
  * Arguments  : *task	解码任务句柄
  *              *wait	解码资源句柄
  * Return	 : 0		成功
  * Note(s)    : 加入链表后，按*wait配置信息播放
  *********************************************************************
  */
  int audio_decoder_task_add_wait(struct audio_decoder_task *task, struct audio_res_wait *wait);
  
  /*
  *********************************************************************
  *                  Audio Decoder Task Delete ResWait
  * Description: 解码任务删除解码通道资源
  * Arguments  : *task	解码任务句柄
  *              *wait	解码资源句柄
  * Return	 : None.
  * Note(s)    : 当前的删除后，如果链表中还有res，按规则继续播放
  *********************************************************************
  */
  void audio_decoder_task_del_wait(struct audio_decoder_task *task, struct audio_res_wait *wait);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Task ResWait state
  * Description: 获取解码任务链表中的资源数量
  * Arguments  : *task	解码任务句柄
  * Return	 : ResWait数量
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_task_wait_state(struct audio_decoder_task *task);
  
  /*
  *********************************************************************
  *                  Audio Decoder Resume All Decoder Channel
  * Description: 激活解码任务链表中的所有解码
  * Arguments  : *task	解码任务句柄
  * Return	 : 0		成功
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_resume_all(struct audio_decoder_task *task);
  
  /*
  *********************************************************************
  *                  Audio Decoder Add Format Lock
  * Description: 解码任务资源添加格式锁
  * Arguments  : *task	解码任务句柄
  *              fmt		解码格式
  * Return	 : 0		成功
  * Note(s)    : 锁定后，后续的解码将不能使用该解码
  *********************************************************************
  */
  int audio_decoder_fmt_lock(struct audio_decoder_task *task, int fmt);
  
  /*
  *********************************************************************
  *                  Audio Decoder Add Format Unlock
  * Description: 解码任务资源格式锁解锁
  * Arguments  : *task	解码任务句柄
  *              fmt		解码格式
  * Return	 : 0		成功
  * Note(s)    : 解锁后，后续的解码可以使用该解码
  *********************************************************************
  */
  int audio_decoder_fmt_unlock(struct audio_decoder_task *task, int fmt);
  
  
  /*
  *********************************************************************
  *                  Audio Decoder Output
  * Description: 解码输出
  * Arguments  : *_dec	解码句柄
  *              *buf		输出buf
  *              len		输出长度
  *              *priv	私有参数
  * Return	 : 输出了多少数据
  * Note(s)    : 解码输出不了会被挂起，需要调用resume激活该解码
  *********************************************************************
  */
  int audio_decoder_put_output_buff(void *_dec, void *buff, int len, void *priv);
  
  /*
  *********************************************************************
  *                  Audio Decoder Read Data
  * Description: 解码读数
  * Arguments  : *_dec	解码句柄
  *              *buf		输出buf
  *              len		输出长度
  *              offset	读数偏移
  * Return	 : 读到了多长（错误返回负数）
  * Note(s)    : 仅文件解码可用
  *********************************************************************
  */
  int audio_decoder_read_data(void *_dec, u8 *data, int len, u32 offset);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Input Len
  * Description: 获取解码文件长度
  * Arguments  : *_dec	解码句柄
  * Return	 : 文件长度
  * Note(s)    : 仅文件解码可用
  *********************************************************************
  */
  int audio_decoder_get_input_data_len(void *_dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Frame Data
  * Description: 获取流数据帧内容
  * Arguments  : *_dec	解码句柄
  *              **frame	返回帧信息
  * Return	 : 帧长度
  * Note(s)    : 仅流数据解码可用
  *********************************************************************
  */
  int audio_decoder_get_frame(void *_dec, u8 **frame);
  
  /*
  *********************************************************************
  *                  Audio Decoder Fetch Frame
  * Description: 检查流数据帧内容
  * Arguments  : *_dec	解码句柄
  *              **frame	返回帧信息
  * Return	 : 帧长度
  * Note(s)    : 仅流数据解码可用。数据没有读走，仅查看内容
  *********************************************************************
  */
  int audio_decoder_fetch_frame(void *_dec, u8 **frame);
  
  /*
  *********************************************************************
  *                  Audio Decoder Put Frame
  * Description: 流数据帧使用完
  * Arguments  : *_dec	解码句柄
  *              *frame	帧信息
  * Return	 : None.
  * Note(s)    : 仅流数据解码可用
  *********************************************************************
  */
  void audio_decoder_put_frame(void *_dec, u8 *frame);
  
  /*
  *********************************************************************
  *                  Audio Decoder Open Channel
  * Description: 打开一个解码通道
  * Arguments  : *dec		解码句柄
  *              *input: 解码输入参数信息
  *              *task: 解码任务句柄
  * Return	 : 0		成功
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_open(struct audio_decoder *dec, const struct audio_dec_input *input,
                         struct audio_decoder_task *task);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Data Type
  * Description: 获取配置的解码类型
  * Arguments  : *_dec	解码句柄
  * Return	 : 解码类型AUDIO_INPUT_FILE或者AUDIO_INPUT_FRAME
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_data_type(void *_dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Format
  * Description: 获取解码器格式信息
  * Arguments  : *_dec	解码句柄
  *              **fmt	获取到的格式信息
  * Return	 : 0		成功
  * Note(s)    : 解码器没有打开时，尝试打开解码器
  *********************************************************************
  */
  int audio_decoder_get_fmt(struct audio_decoder *dec, struct audio_fmt **fmt);
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Format
  * Description: 设置解码的格式信息
  * Arguments  : *_dec	解码句柄
  *              *fmt		格式信息
  * Return	 : 0		成功
  * Note(s)    : 直接指定解码格式，如sbc解码等
  *********************************************************************
  */
  int audio_decoder_set_fmt(struct audio_decoder *dec, struct audio_fmt *fmt);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Format Info
  * Description: 实时获取解码器格式信息
  * Arguments  : *dec		解码句柄
  *              *fmt		获取到的格式信息
  * Return	 : 0		成功
  * Note(s)    : 需要在解码成功后才能调用。函数中调用解码器get_fmt()接口
  *********************************************************************
  */
  int audio_decoder_get_fmt_info(struct audio_decoder *dec, struct audio_fmt *fmt);
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Deal Handler
  * Description: 设置解码处理handler
  * Arguments  : *dec		解码句柄
  *              *handler	解码处理handler
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_set_handler(struct audio_decoder *dec, const struct audio_dec_handler *handler);
  
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Event Handler
  * Description: 设置解码事件回调
  * Arguments  : *dec		解码句柄
  *              *handler	回调函数
  *              maigc	私有标识
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_set_event_handler(struct audio_decoder *dec,
                                       void (*handler)(struct audio_decoder *, int, int *), u32 magic);
  
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Output Channel
  * Description: 设置解码输出声道类型
  * Arguments  : *dec		解码句柄
  *              channel	声道类型
  * Return	 : 0		成功
  * Note(s)    : 函数中调用解码器set_output_channel()接口
  *********************************************************************
  */
  int audio_decoder_set_output_channel(struct audio_decoder *dec, enum audio_channel);
  
  /*
  *********************************************************************
  *                  Audio Decoder Start
  * Description: 启动解码
  * Arguments  : *dec		解码句柄
  * Return	 : 0		成功
  * Note(s)    : 函数中调用解码器start()接口
  *********************************************************************
  */
  int audio_decoder_start(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Stop
  * Description: 停止解码
  * Arguments  : *dec		解码句柄
  * Return	 : 0		成功
  * Note(s)    : None
  *********************************************************************
  */
  int audio_decoder_stop(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Pause
  * Description: 解码暂停
  * Arguments  : *dec		解码句柄
  * Return	 : 0		成功
  * Note(s)    : None
  *********************************************************************
  */
  int audio_decoder_pause(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Suspend
  * Description: 解码挂起
  * Arguments  : *dec		解码句柄
  * Return	 : 0		成功
  * Note(s)    : None
  *********************************************************************
  */
  int audio_decoder_suspend(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Resume
  * Description: 解码挂起激活
  * Arguments  : *dec		解码句柄
  * Return	 : 0		成功
  * Note(s)    : None
  *********************************************************************
  */
  int audio_decoder_resume(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Close
  * Description: 关闭解码
  * Arguments  : *dec		解码句柄
  * Return	 : 0		成功
  * Note(s)    : None
  *********************************************************************
  */
  int audio_decoder_close(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Reset
  * Description: 解码器reset
  * Arguments  : *dec		解码句柄
  * Return	 : 0		成功
  * Note(s)    : 函数中调用解码器reset()接口
  *********************************************************************
  */
  int audio_decoder_reset(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Breakpoint Handler
  * Description: 设置解码断点句柄
  * Arguments  : *dec		解码句柄
  *              *bp		断点句柄
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_set_breakpoint(struct audio_decoder *dec, struct audio_dec_breakpoint *bp);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Breakpoint
  * Description: 获取解码断点信息
  * Arguments  : *dec		解码句柄
  *              *bp		断点句柄
  * Return	 : 0		成功
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_get_breakpoint(struct audio_decoder *dec, struct audio_dec_breakpoint *bp);
  
  /*
  *********************************************************************
  *                  Audio Decoder Forward
  * Description: 解码快进
  * Arguments  : *dec		解码句柄
  *              step_s	快进步伐（按秒计数）
  * Return	 : 0		成功
  * Note(s)    : 函数中调用解码器fast_forward()接口
  *********************************************************************
  */
  int audio_decoder_forward(struct audio_decoder *dec, int step_s);
  
  /*
  *********************************************************************
  *                  Audio Decoder Rewind
  * Description: 解码快退
  * Arguments  : *dec		解码句柄
  *              step_s	快退步伐（按秒计数）
  * Return	 : 0		成功
  * Note(s)    : 函数中调用解码器fast_rewind()接口
  *********************************************************************
  */
  int audio_decoder_rewind(struct audio_decoder *dec, int step_s);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Total Time
  * Description: 获取解码总时间
  * Arguments  : *dec		解码句柄
  * Return	 : 解码总时间
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_get_total_time(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Play Time
  * Description: 获取解码当前时间
  * Arguments  : *dec		解码句柄
  * Return	 : 解码当前时间
  * Note(s)    : 函数中调用解码器get_play_time()接口
  *********************************************************************
  */
  int audio_decoder_get_play_time(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Pick Status
  * Description: 设置解码拆包模式
  * Arguments  : *dec		解码句柄
  *              pick		拆包使能
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_set_pick_stu(struct audio_decoder *dec, u8 pick);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Pick Status
  * Description: 获取解码拆包模式
  * Arguments  : *dec		解码句柄
  * Return	 : 1		拆包
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_get_pick_stu(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Tws Status
  * Description: 设置解码tws模式
  * Arguments  : *dec		解码句柄
  *              tws		tws模式使能
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_set_tws_stu(struct audio_decoder *dec, u8 tws);
  
  /*
  *********************************************************************
  *                  Audio Decoder Get Tws Status
  * Description: 获取解码tws模式
  * Arguments  : *dec		解码句柄
  * Return	 : 1		tws模式
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_get_tws_stu(struct audio_decoder *dec);
  
  /*
  *********************************************************************
  *                  Audio Decoder Set Max Run Number
  * Description: 设置解码每次轮询可执行的最大次数
  * Arguments  : *dec		解码句柄
  *              run_max	最大次数
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_set_run_max(struct audio_decoder *dec, u8 run_max);
  
  /*
  *********************************************************************
  *                  Audio Decoder Dual Channel Switch To Other
  * Description: 双声道转换为其他声道
  * Arguments  : ch_type	输出声道类型
  *              half_lr	合并声道是否除2
  *              *data	数据
  *              len		数据长度
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_dual_switch(u8 ch_type, u8 half_lr, s16 *data, int len);
  
  /*
  *********************************************************************
  *                  Audio Decoder Find Coding Type Have Used
  * Description: 检查解码器是否已经使用
  * Arguments  : *task	解码任务句柄
  *              coding_type	解码器类型
  * Return	 : 1		已经使用
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_find_coding_type(struct audio_decoder_task *task, u32 coding_type);
  
  /*
  *********************************************************************
  *                  Audio Decoder Check Running Decoder Number
  * Description: 统计正在运行的解码数
  * Arguments  : *task	解码任务句柄
  * Return	 : 正在运行的解码数
  * Note(s)    : 统计解码状态为DEC_STA_START或者DEC_STA_WAIT_RESUME
  *********************************************************************
  */
  int audio_decoder_running_number(struct audio_decoder_task *task);
  
  /*
  *********************************************************************
  *                  Audio Decoder Ioctrl
  * Description: 解码器控制
  * Arguments  : *dec		解码句柄
  *              cmd		控制命令
  *              *parm	控制参数
  * Return	 : 0		成功
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_ioctrl(struct audio_decoder *dec, u32 cmd, void *parm);
  
  
  /*
  *********************************************************************
  *                  Audio Decoder Output Task Create
  * Description: 创建解码输出任务
  * Arguments  : *task	任务句柄
  *              *out_task_name	解码输出任务名
  * Return	 : 0		成功
  * Note(s)    : None.
  *********************************************************************
  */
  int audio_decoder_out_task_create(struct audio_decoder_task *task, const char *out_task_name);
  
  /*
  *********************************************************************
  *                  Audio Decoder Output Task Destroy
  * Description: 删除解码输出任务
  * Arguments  : *task	任务句柄
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_out_task_destroy(struct audio_decoder_task *task);
  
  /*
  *********************************************************************
  *                  Audio Decoder Output Task Channel Enable
  * Description: 设置解码输出任务使能
  * Arguments  : *dec		解码句柄
  *              len		输出缓存长度
  * Return	 : 0		成功
  * Note(s)    : 当解码输出长度大于设置的长度时，会关闭该通道输出任务使能
  *********************************************************************
  */
  int audio_decoder_out_task_ch_enable(struct audio_decoder *dec, int len);
  
  /*
  *********************************************************************
  *                  Audio Decoder Resume Output Task
  * Description: 激活解码输出任务
  * Arguments  : *dec		解码句柄
  * Return	 : None.
  * Note(s)    : None.
  *********************************************************************
  */
  void audio_decoder_resume_out_task(struct audio_decoder *dec);
  
  
  #endif
  
  