//
//  libstruct.h
//
//  Created by powersmart on 15/9/16.
//  Copyright (c) 2015年 PowerSmart. All rights reserved.
//

#ifndef libstruct_h
#define libstruct_h

//the video capture device number
#define CAMERA_NUM 1

//the number of encoder for video
#define ENCODER_VIDEO_NUM 1

//the number of encoder for audio
#define ENCODER_AUDIO_NUM 1

//the number of packer
#define PSLSTREAMING_NUM 1

#define AVCAPPRESET1280x720  0
#define AVCAPPRESET640x480    1
#define AVCAPPRESET352x288    2

#define ENCODE_AAC          11
#define ENCODE_AACPLUS      12

/**
 struct for capture, used by capture module
 */
typedef struct _CAPTURE_CONFIG
{
    /**
     it's not in use
     
     capture resolution
     the width and height of the video you want to send to viewer
     you need not consider the rotation of video here, the value of width should always larger than value of height
     for example, if you want set 800x450(landscape) or 450x800(portrait), just set width=800 and height=450
     */
    int     width;
    int     height;
    
    /**
     encoder flag means if the data from capture will send to encoder
     set to 0 if you do not want capture data be sended to encoder
     set to 1 if you do want capture data be sended to encoder
     */
    int     encoder_flag;
    
    /**
     to choose front camera or back camera
     0 for front camera
     1 for back camera
     */
    int     mode;
    
    /**
     capture fps
     set the capture fps that you want, set the same value with video fps
     actual capture fps may be low than this value according network conditions
     */
    int fps;
    
    /**
     set sessionPreset for avcapturesession
     0 for AVCaptureSessionPreset1280x720
     1 for AVCaptureSessionPreset640x480
     2 for AVCaptureSessionPreset352x288
     */
    int avcap_preset;
    
}CAPTURE_CONFIG, *PCAPTURE_CONFIG;

typedef struct _BUFFER_INFO
{
    /**
     0 stands for video
     1 stands for audio
     */
    int             type;
    
    /**
     the size of buf that will send to PSLStreaming, unit: bytes
     */
    int             size;
    
    /**
     for video
     0 for idr frame
     1 for other frame（b frame or p frame）
     */
    unsigned int    flag;
    
    /**
     pts and dts
     unit is 1/10000000 s
     for video
     if there has not B frame, dts set the same number with pts
     if there has B frame, dts shuold get frome Encoder, Past experience has taught us that the dts from Encoder isn't meeting expectations
     for audio
     just set pts
     */
    long long         pts;
    long long         dts;
}BUFFER_INFO,*PBUFFER_INFO;

/**
 struct for video param, used by video encoder and PSLStreaming
 */
typedef struct _H264_IOS_PARAM
{
    /**
     switch of video stream
     if format=0, then video stream will not be pushed to network
     if format=1, then video stream will be pushed
     */
    int format;
    
    /**
     video resolution
     the width and height of the video stream
     in this struct, you need consider the rotation of video here, the value of width may not be larger than value of height
     for example, if you want set 800x450(landscape) or 450x800(portrait), then you should set width=800 & height=450 in landscape mode and you should set width=450 & height=800 in portrait mode
     */
    int width;
    int height;
    
    /**
     video bitrate, unit: b/s
     */
    int bitrate;
    
    /**
     video fps
     set the video fps that you want, actual video fps may be low than this value according network conditions
     */
    int fps;
    
    
    /**
     maxkeyFrameInterval: video frames between each key frame, we usually set 2*fps to it
     */
    int maxkeyFrameInterval;
    
    /**
     used for iOS VIDEO_TOOLBOX
     profile is construct of three number, such as 130、242、300;
     the first number means the level of profile: 1 for Baseline、2 for Main、3 for High
     the seceond and third number is for level, more info you can see follow example
     if the sencond and third number all are zero, that is mean it's auto_level
     default profile is 350, kVTProfileLevel_H264_High_5_0
     for example:
     130 is Baseline_level_3_0, that means 1 for Baseline, 30 for 3_0
     342 is High_level_4_2, that means 3 for High, 42 for 4_2
     200 is Main_level_auto, that means 2 for Main, 00 for auto
     */
    int profile;
    
    /**
     switch of Bframe
     if Bframeflag=1, encoder will export B frame according encode rule
     if Bframeflag=0, encoder will not export B frame
     */
    int Bframeflag;
    
    /**
     the second between each key frame
     we usually get this value by maxkeyFrameInterval/fps.
     */
    float keyinterval_sec;
    
}*PH264_IOS_PARAM, H264_IOS_PARAM, ENCODER_VIDEO_CONFIG, *PENCODER_VIDEO_CONFIG;

/**
 struct for Audio Param, used by audio capture and audio encoder and PSLStreaming
 */
typedef struct _AUDIO_PARAM
{
    /**
     switch of audio stream
     if format=0, then audio stream will not be pushed to network
     if format=1, then audio stream will be pushed, in addition, audio stream format should be AAC LC
     if format=2, then audio stream will be pushed, in addtion, audio stream format should be HE AAC
     */
    int format;
    
    /**
     audio params
     audio bitrate unit: bps
     audio samplerate unit: Hz
     encodertype : 0 for software encoder, 1 for hardware encoder
     
     matters that need atention:
     if the value between channelnum and bitrate is not matching, the audio encoder's init function will return a error. for example, if audio channelnum is 2, then audio bitrate should be larger than 64000.
     */
    int bitrate;
    int samplerate;
    int channelnum;
    int encodertype;
    
    unsigned int extrasize;
    unsigned char extrainfo[256];
}AUDIO_PARAM, *PAUDIO_PARAM, ENCODER_AUDIO_CONFIG, *PENCODER_AUDIO_CONFIG;

/**
 struct for PSLStreaming, used by PSLStreaming module
 */
typedef struct _PSLSTREAMING_CONFIG
{
    /**
     the max Delay that lib can accept, if delay is larger than this value, lib will not send video data
     unit: millisecond
     */
    int target_delayms;
    
    /**
     if txtype=0, push library will only use single path
     if txtype=1, push library will only use multipath
     
     matters that need atention: you shuold set txtype=1 for a wonderful effect
     */
    int txtype;
    
    /**
     set the address you want to PSLStreaming push stream to
     more info refering to url rule document
     */
    char url[512];
    
    /**
     value scale: [0, 100]
     0   for smoothest
     100 for highest quality
     */
    int adjust_quality_ratio;
    
    /**
     threshold params
     adjust_fps_minratio: value scale is [0, 100], calculate through 100*fps_min/video_fps, more info refer to fps_min in struct INTERFACE_SET_PARAMS
     adjust_br_maxratio: value scale is [0, 100], calculate through 100*br_max/video_bitrate, more info refer to br_max in struct INTERFACE_SET_PARAMS
     adjust_br_minratio: value scale is [0, 100], calculate through 100*br_min/video_bitrate, more info refer to br_min in struct INTERFACE_SET_PARAMS
     */
    int adjust_fps_minratio;
    int adjust_br_maxratio;
    int adjust_br_minratio;
    
}PSLSTREAMING_CONFIG, *PPSLSTREAMING_CONFIG;


/**
 core struct, used by all module
 */
typedef struct _INTERFACE_PARAMS
{
    CAPTURE_CONFIG              cameraconfig[CAMERA_NUM];
    ENCODER_AUDIO_CONFIG        audioencoderconfig[ENCODER_AUDIO_NUM];
    ENCODER_VIDEO_CONFIG        videoencoderconfig[ENCODER_VIDEO_NUM];
    PSLSTREAMING_CONFIG         pslstreamingconfig[PSLSTREAMING_NUM];
    
    /**
     audio encoder format
     if aencodertype = ENCODE_AAC, means audio encoder format AAC LC
     if aencodertype = ENCODE_AACPLUS, means audio encoder format HE-AAC
     */
    int                         aencoderformat;
    
    /**
     params about delay:
     delaysstatus: if current delay is larger than maxDelayThreshold, delaystatus is -1, else delaystatus is 0
     delayms: current delayms in push module
     */
    int                         delaystatus;
    int                         delayms;
    
    /**
     if networkstatus is -1, that mean push module anomaly
     if networkstatus is 0, that mean push module work allright
     */
    int                         networkstatus;
    
    /**
     if capturestatus = -1,that mean video capture is error
     if capturestatus = -2,that mean  audio capture is error
     if capturestatus = 0,that mean  capture is allright
     */
    int                         capturestatus;
    
}INTERFACE_PARAMS, *PINTERFACE_PARAMS;

#endif
