//
// The data structure of the streaming video:
// [16-byte tBasicIdx header] + [16-byte tExtraIdx header] + ['SuperExtraSize' bytes] + [32-byte PES header] + [video body]
// The 'SuperExtraSize' is defined in the 'tExtraIdx' structure to store the additional information, and usually equals zero.
//
// You can include the following structures to you c++ project for parsering the related model's video streaming.
//
#ifndef DVR_EXTRA_DATA_MAX_LENGTH
#define DVR_EXTRA_DATA_MAX_LENGTH 96
#endif
//
// streaming header 
//
typedef struct
{
	tBasicIdx Basic;
	tExtraIdx Extra;
}tHeader;

//
//    Big Endian: DG700N, DG700N2, DG900G1, DG900G2
// Little Endian: L8XG2, T-Series, I-Series 
//

#ifdef BIG_ENDIAN_MACHINE
//
// ====================
//     Big Endian
// ====================
// Basic Idx: 16 bytes
// - big endian
//
typedef struct
{
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	// Header1 & Header2 are for big/little endian indication
	// "@6"          is for big endian
	// "@2" or "@8" are for little endian
	//
	unsigned int Header1    :8; // [2] 
	unsigned int Header2    :8; // [2] 
	//
	// reserved.
	// - no in use
	//
	unsigned int reserved   :4; // 4 bits
	unsigned int Source	:1; // 1 bit  : (0 - DVR, 1 - IP Dev)
	unsigned int WidthBase	:2; // 0:720 , 1:704, 2:640
        unsigned int Reserved0  :1; // 1 bit  : (0 - Disable(backward compatibile), 1 - Enable)
	unsigned int WidthBase  :2; // 0:720, 1:704, 2:640
	unsigned int Source     :1; // 1 bit : (0 - DVR, 1 - IP Dev)
	unsigned int Msec       :4; // 4 bits : 66 msec
	unsigned int QI         :4; // 4 bits : QI (0~16)
	unsigned int StreamType :2; // 0: normal stream, 1: V stream, 2: Dual stream, 3: others
        //
        // this is basically for VSS use since VSS needs to support 96 channels, and
        // there is originally 5 bits only for channel number in the header.
        // With these two extra bits, the channel number becomes ((Channel_Ext<<5)|Channel).
        //
	unsigned int Channel_Ext:2;
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
	unsigned int Size;           // 4-byte
	unsigned int Time;           // 4-byte
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	unsigned int Motion     :1;  // 1 bit : Motion
	unsigned int AlarmIn    :1;  // 1 bit : Alarm In
	unsigned int Vloss      :1;  // 1 bit : Video loss
	unsigned int Covert     :1;  // 1 bit : Covert
	unsigned int DST        :1;  // 1 bit : DST
	unsigned int Audio      :1;  // 1 bit : 0:Video/1:Audio
	unsigned int ImgMode    :1;  // 1 bit : 0:Live/1:Playback
	unsigned int NTSC_PAL   :1;  // 1 bit : 0:NTSC/1:PAL

	unsigned int PPS        :6;  // 6 bits : Per-channel PPS Idx (0~127 level)
	unsigned int EventEnable:1;  // 1 bit  : 0: Normal status    1: Event duration
	unsigned int ExtraEnable:1;  // 1 bit  : 0: no extra         1: have extra
	
	unsigned int Channel    :5;  // 5 bits : Channel No (0~31)
	unsigned int Type       :3;  // 3 bits : type (0~7) 0: none 1: I-pic, 2: P-Pic, 3: B-Pic
	unsigned int Chksum     :8;              // [1]
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
} tBasicIdx;
//
// - big endian
//
typedef struct
{
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	unsigned int   DST_Minutes    :8;
	unsigned int   Exception      :1;
	unsigned int   SkipPicCnt     :5;
	unsigned int   OverSpeed      :1;
	unsigned int   IsDST_S_W      :1;  //0 = summer time ,1 = winter time
	unsigned int   SuperExtraSize :16;
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
	unsigned int   Serno;       // 4-byte
	//
	// Original tEventInfo16CH was broken 'cause of the byte alignment problem
	// - use the following directly
	//
	// ===== Start =====
	//
	// the definition of pHdr->Extra.Vloss[] is the vloss status of current channel type
	// - if it's an analog cam, the Vloss[] stands for analog cam's vloss
	//   if it's an IP cam, the Vloss[] stands for IP cam's
	// - the same is applied to pHdr->Extra.Motion[] & pHdr->Extra.AlmIn[]
	//
	char AlmIn[2];              // 16 channel
	char Vloss[2];              // 16 channel
	char Motion[2];             // 16 channel
	unsigned char  TimeZone:6;
	unsigned char  IsDVRRec:2;
	char Chksum;                // 1-byte 
}tExtraIdx;
//
// Extra Idx: 16 bytes
// - big endian
//
typedef struct
{
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	unsigned int   DST_Minutes	  :8;
	unsigned int   Unused             :1;
	unsigned int   SkipPicCnt         :5;
	unsigned int   IsStereo           :1; // 0 = mono       , 1 = stereo.
	unsigned int   IsDST_S_W	  :1; // 0 = summer time, 1 = winter time
	unsigned int   SuperExtraSize     :16;
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
	unsigned int   Serno;			// [4] 
	//
	// Original tEventInfo16CH was broken 'cause of the byte alignment problem
	// - use the following directly
	//
	// ===== Start =====
	//
	unsigned short FormatTag;     // audio format tag followed MS's definition
	unsigned short BitsPerSample; // bits per sample (eg. 8, 16, or 24)
	unsigned short SamplesPerSec; // samples per second (eg. 8000, 16000, or 44100)
	//
	// ===== End =====
	//
	unsigned char  TimeZone:6;  
	unsigned char  IsDVRRec:2;
	char Chksum;                  // 1-byte
}tIPExtraIdx;
#else
//
// ====================
//     Little Endian
// ====================
//
// Basic Idx: 16 bytes
// - for little Endian
//
typedef struct
{
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	// Header1 & Header2 are for big/little endian indication
	// "@6"          is for big endian
	// "@2" or "@8" are for little endian
	//
        unsigned int Header1    :8; // [2] 
        unsigned int Header2    :8; // [2] 
        unsigned int Msec       :4; // 4 bits : 66 msec
        unsigned int Source     :1; // 1 bit  : (0 - DVR, 1 - IP Dev)
	unsigned int WidthBase  :2; // 0:720 , 1:704, 2:640
	unsigned int Reserved0  :1; // 1 bit  : (0 - Disable(backward compatibile), 1 - Enable)
	//
	// this is basically for VSS use since VSS needs to support 96 channels, and
	// there is originally 5 bits only for channel number in the header.
	// With these two extra bits, the channel number becomes ((Channel_Ext<<5)|Channel).
	//
	unsigned int Channel_Ext:2;
	unsigned int StreamType :2; // 0: normal stream, 1: V stream, 2: Dual stream, 3: others
	unsigned int QI         :4; // 4 bits : QI (0~16)
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
	unsigned int Size;      // 4-byte
	time_t Time;            // 4-byte
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	unsigned int NTSC_PAL   :1;  // 1 bit : 0:NTSC/1:PAL
	unsigned int ImgMode    :1;  // 1 bit : 0:Live/1:Playback
	unsigned int Audio      :1;  // 1 bit : 0:Video/1:Audio
	unsigned int DST        :1;  // 1 bit : DST
	unsigned int Covert     :1;  // 1 bit : Covert
	unsigned int Vloss      :1;  // 1 bit : Video loss
	unsigned int AlarmIn    :1;  // 1 bit : Alarm In
	unsigned int Motion     :1;  // 1 bit : Motion

	unsigned int ExtraEnable:1;  // 1 bit  : 0: no extra         1: have extra
	unsigned int EventEnable:1;  // 1 bit  : 0: Normal status    1: Event duration
	unsigned int PPS        :6;  // 6 bits : Per-channel PPS Idx (0~127 level)

	unsigned int Type       :3;  // 3 bits : type (0~7) 0: none 1: I-pic, 2: P-Pic, 3: B-Pic
	unsigned int Channel    :5;  // 5 bits : Channel No (0~31)
	unsigned int Chksum     :8;              // [1]
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
} tBasicIdx;
//
// Extra Idx: 16 bytes
// - for little Endian
//
typedef struct
{
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	unsigned int   IsDST_S_W      :1; //   0 = summer time , 1 =winter time
	unsigned int   DST_Minutes    :8; // 0~7 = 0 ~ 120 minutes
	unsigned int   OverSpeed      :1;
	unsigned int   SkipPicCnt     :5;
	//
	// use one bit to represent exception alarm
	//  - can't get exactually exception no here
	//
	unsigned int   Exception      :1;
	unsigned int   SuperExtraSize :16;
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
	unsigned int   Serno; // 4-byte
	//
	// Original tEventInfo16CH was broken 'cause of the byte alignment problem
	// - use the following directly
	//
	// ===== Start =====
	//
	// the definition of pHdr->Extra.Vloss[] is the vloss status of current channel type
	// - if it's an analog cam, the Vloss[] stands for analog cam's vloss
	//   if it's an IP cam, the Vloss[] stands for IP cam's
	// - the same is applied to pHdr->Extra.Motion[] & pHdr->Extra.AlmIn[]
	//
	char AlmIn[2];          // 16 channel
	char Vloss[2];          // 16 channel
	char Motion[2];         // 16 channel
	//
	// ===== End =====
	//
	unsigned char  IsDVRRec:2;
	//
	// For TimeZone setting
	// - 0 means OFF (backward compatibility)
	// - Delta : 30 min
	// - Start from : -12:00
	// - Aka.
	//    1 : -12:00 (-720 min)
	//    2 : -11:30 (-690 min)
	//    3 : -11:00 (-660 min)
	//    ....
	//   25 : +00:00 (+000 min)
	//    ....
	//   41 : +08:00 (+480 min)
	//   42 : +08:30 (+510 min)
	//   43 : +09:00 (+540 min)
	//    ....
	//   51 : +13:00 (+780 min)
	//
        unsigned char  TimeZone:6;
        char           Chksum;               // 1-byte
} tExtraIdx;
//
// - for little Endian
//
typedef struct
{
	// ====================================================================================
	// total 4-byte - [!!! Start !!!]
	//
	unsigned int   IsDST_S_W      :1; // 0 = summer time ,1 = winter time
	unsigned int   DST_Minutes    :8; // 0~7 = 0 ~ 120 minutes
	unsigned int   IsStereo       :1; // 0: mono, 1:stereo.
	unsigned int   SkipPicCnt     :5;
	unsigned int   Unused         :1;
	unsigned int   SuperExtraSize :16;
	//
	// total 4-byte - [!!! End !!!]
	// ====================================================================================
	unsigned int   Serno;            // 4-byte
	//
	// ===== Start =====
	//
	unsigned short FormatTag;        // audio format tag followed MS's definition
	unsigned short BitsPerSample;    // bits per sample (eg. 8, 16, or 24)
	unsigned short SamplesPerSec;    // samples per second (eg. 8000, 16000, or 44100)
	//
	// ===== End  ======
	//
	unsigned char  IsDVRRec:2;
	//
	// For TimeZone setting
	// - 0 means OFF (backward compatibility)
	// - Delta : 30 min
	// - Start from : -12:00
	// - Aka.
	//    1 : -12:00 (-720 min)
	//    2 : -11:30 (-690 min)
	//    3 : -11:00 (-660 min)
	//    ....
	//   25 : +00:00 (+000 min)
	//    ....
	//   41 : +08:00 (+480 min)
	//   42 : +08:30 (+510 min)
	//   43 : +09:00 (+540 min)
	//    ....
	//   51 : +13:00 (+780 min)
	//
	unsigned char  TimeZone:6;
	char           Chksum;           // 1-byte
}tIPExtraIdx;
#endif // end BIG_ENDIAN_MACHINE

//
// enum description for SuperExtra data
//
enum
{
	REC_INDEX_TYPE_GPS = 0x00,
	REC_INDEX_TYPE_POS = 0x01,
	REC_INDEX_TYPE_UNITNAME = 0x03,
	//
	// GPS way point
	// - not in used for DVR/NVR
	//
	REC_INDEX_TYPE_WAYPOINT = 0x04,
	//
	// motion status
	//
	REC_INDEX_TYPE_MOTION_STATUS = 0x05,
	//
	// G-sensor
	// - not in used for DVR/NVR
	//
	REC_INDEX_TYPE_G_SENSOR = 0x06,
	//
	// Tire Pressure Monitor System
	//
	REC_INDEX_TYPE_TPMS = 0x07,
	REC_INDEX_TYPE_FISHEYE = 0x08,
	REC_INDEX_TYPE_LONG_UNICODE = 0x09,
	REC_INDEX_EXTRA_MOTION_STATUS = (DVR_EXTRA_DATA_MAX_LENGTH-4),
	REC_INDEX_EXTRA_TYPE = (DVR_EXTRA_DATA_MAX_LENGTH-3),
	REC_INDEX_EXTRA_CH = (DVR_EXTRA_DATA_MAX_LENGTH-2),
	REC_INDEX_EXTRA_LENGTH = (DVR_EXTRA_DATA_MAX_LENGTH-1),
};
//
// Super Extra Index :
//  type = 
//  remain_size = 108
// structure to store cam title & extra data(GPS/Text)
//
typedef struct
{
	//
	// the type for tSuperExtraIdx is fixed to 0
	//
	int type;
	//
	// the remain_size for tSuperExtraIdx is fixed to : 108 bytes
	// - 12(title) + 96(DVR_EXTRA_DATA_MAX_LENGTH) = 108
	//
	int remain_size;
	//
	// CAM_TITLE_LEN
	//
	char title[12];
	//
	// merge original account0 ~ account3
	// - GPS & Text support will use the same place
	// - REC_INDEX_EXTRA_TYPE, REC_INDEX_EXTRA_CH, REC_INDEX_EXTRA_LENGTH are
	//   used for some specific info
	//
/*
	//
	// Let's take fish-eye at local DVR-side for example.
	//
	tRTSPFishEyeInfo fish_eye;
	...
	tSuperExtraIdx SpExtra;
	memset(&SpExtra, 0, sizeof(tSuperExtraIdx));
	//
	// remain_size = 108
	//
	SpExtra.remain_size = 108;
	//
	// the size of tRTSPFishEyeInfo struct must be smaller than 96 bytes
	// - in order to fit in extra_data[DVR_EXTRA_DATA_MAX_LENGTH]
	//
	memcpy(SpExtra.extra_data,&fish_eye,sizeof(tRTSPFishEyeInfo));
	//
	// fill in the data type of this super extra data
	//
	SpExtra.extra_data[REC_INDEX_EXTRA_TYPE] = REC_INDEX_TYPE_FISHEYE;
	//
	// fill in the channel info
	// - take channl 4 for example. 
	// - channel count starts from 0
	//
	SpExtra.extra_data[REC_INDEX_EXTRA_CH] = 3;
	//
	// the valid range size of this super extra package
	//
	SpExtra.extra_data[REC_INDEX_EXTRA_LENGTH] = sizeof(tRTSPFishEyeInfo);
*/
	char extra_data[DVR_EXTRA_DATA_MAX_LENGTH];
} tSuperExtraIdx;

//
// the data structure that illustrate the fish-eye info
// - total size 32-byte
//
typedef struct
{
	//
	// view width
	//
	int view_width;
	//
	// view height
	//
	int view_height;
	//
	// center x
	//
	int center_x;
	//
	// center y
	//
	int center_y;
	//
	// diameter
	//
	int diameter;
	//
	// focal length
	//
	int focal_length;
	//
	// reserved 8-byte
	//
	char reserved[8];

} tRTSPFishEyeStreamInfo;

typedef struct
{
	//
	// valid fish-eye info
	// - bit0 : for valid normal stream
	// - bit1 : for valid sub-stream
	//
	int valid_info;
	//
	// image appearance / rotation
	// - 0,flip,mirror,rotate,clockwise,counter-clockwise
	//
	char rotation;
	//
	// view location
	// - ceiling, wall
	//
	char location;
	//
	// wall angle
	// - range: 0~359
	//
	int wall_angle;
	//
	// projection type
	// - stereo graphic, equidistant
	//
	char projection;
	//
	// reserved space
	// - padding for 16-byte length
	//
	char reserved[5];
	//
	// stream info
	// - 0 for Normal Stream
	// - 1 for vstream
	//   - DVR/NVR side : vstream
	//   -     CMS side : substream
	//
	tRTSPFishEyeStreamInfo stream[2];

}tRTSPFishEyeInfoDb;

typedef struct
{
	// 4 bytes
	unsigned int start_code0:8;  // must be 0x00
	unsigned int start_code1:8;  // must be 0x00
	unsigned int start_code2:8;  // must be 0x01
	unsigned int channel_id:4;   // channel id from 0 to 15 for CH1 to CH16
	unsigned int format_id:4;    // JPEG:0xd, MPEG4:0xe, H.264:0xf, Audio:0xc
	// 4 bytes
	unsigned int unused_0;
	// 4 bytes
	unsigned int unused_1;
	// 4 bytes
	unsigned int unused_2;
	// 4 bytes
	unsigned int unused_3;
	// 4 bytes
	unsigned int unused_4;
	//
	// size of the video body and this PES header (total 3 bytes including the markers)
	//
	unsigned int size_bit21to15:7;  // from bit21 to bit15
	unsigned int size_marker0:1;    // must be 0x1
	unsigned int size_bit10to8:3;   // from bit10 to bit8
	unsigned int size_marker1:1;	// must be 0x1
	unsigned int size_bit14to11:4;  // from bit14 to bit11
	unsigned int size_bit7to0:8;    // from bit7 to bit0
	// 1 byte for the picture type
	unsigned int picture_type:8;    // 1: I-slice, 2: P-slice, 3: B-slice

	unsigned int is_interleaved:1;  // 0: even/odd fields are separated horizontally
	                                // 1: even/odd fields are interleaved
	unsigned int field_id:2;        // 0: odd field, 1: even field, 2/3: undefined
	unsigned int unused_5:29;

}tPesHeader;
