/*
 *******************************************************************************
 *  Copyright (c) 2010-2022 VATICS(KNERON) Inc. All rights reserved.
 *
 *  +-----------------------------------------------------------------+
 *  | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
 *  | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH  |
 *  | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
 *  | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE   |
 *  | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE   |
 *  | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.        |
 *  |                                                                 |
 *  | THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT   |
 *  | ANY PRIOR NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY |
 *  | VATICS(KNERON) INC.                                             |
 *  +-----------------------------------------------------------------+
 *
 *******************************************************************************
 */
#ifndef __MP4_TYPES_H__
#define __MP4_TYPES_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <mp4_reader/mp4_utils.h>
//#include "mp4_utils.h"
#include <stdint.h>
#include <stdio.h>

#define PACKED_STRUCT   __attribute__((__packed__))

#define FOURCC_ftyp     (MAKEFOURCC('f','t','y','p'))

#define FOURCC_free     (MAKEFOURCC('f','r','e','e'))

#define FOURCC_mdat     (MAKEFOURCC('m','d','a','t'))
#define FOURCC_moov     (MAKEFOURCC('m','o','o','v'))
#define FOURCC_mvhd     (MAKEFOURCC('m','v','h','d'))

#define FOURCC_trak     (MAKEFOURCC('t','r','a','k'))
#define FOURCC_tkhd     (MAKEFOURCC('t','k','h','d'))
#define FOURCC_edts     (MAKEFOURCC('e','d','t','s'))
#define FOURCC_mdia     (MAKEFOURCC('m','d','i','a'))

#define FOURCC_mdhd     (MAKEFOURCC('m','d','h','d'))

#define FOURCC_hdlr     (MAKEFOURCC('h','d','l','r'))
#define FOURCC_vide     (MAKEFOURCC('v','i','d','e'))
#define FOURCC_soun     (MAKEFOURCC('s','o','u','n'))


#define FOURCC_minf     (MAKEFOURCC('m','i','n','f'))
#define FOURCC_vmhd     (MAKEFOURCC('v','m','h','d'))
#define FOURCC_smhd     (MAKEFOURCC('s','m','h','d'))
#define FOURCC_dinf     (MAKEFOURCC('d','i','n','f'))

#define FOURCC_stbl     (MAKEFOURCC('s','t','b','l'))
#define FOURCC_stsd     (MAKEFOURCC('s','t','s','d'))
#define FOURCC_stss     (MAKEFOURCC('s','t','s','s'))
#define FOURCC_stts     (MAKEFOURCC('s','t','t','s'))
#define FOURCC_stsc     (MAKEFOURCC('s','t','s','c'))
#define FOURCC_stsz     (MAKEFOURCC('s','t','s','z'))
#define FOURCC_stco     (MAKEFOURCC('s','t','c','o'))
#define FOURCC_co64     (MAKEFOURCC('c','o','6','4'))
#define FOURCC_stxx     (MAKEFOURCC('s','t','x','x'))





#define FOURCC_BI_RGB 0x00000000
#define FOURCC_BI_BITFIELDS 0x00000003

#define SWAP32(x)	((((x)&0xFF000000)>>24) | (((x)&0xFF0000)>>8) | (((x)&0xFF00)<<8) | (((x)&0xFF)<<24))
#define SWAP16(x)	((((x)&0xFF00)>>8) | (((x)&0xFF)<<8))
#define SWAP64(x) ((((uint64_t)x << 56) | (((uint64_t)x << 40) & 0x00ff000000000000LL) | \
                    (((uint64_t)x << 24) & 0x0000ff0000000000LL) | (((uint64_t)x << 8) & 0x000000ff00000000LL) | \
                    (((uint64_t)x >> 8) & 0x00000000ff000000LL) | (((uint64_t)x >> 24) & 0x0000000000ff0000LL) | \
                    (((uint64_t)x >> 40) & 0x000000000000ff00LL) | (((uint64_t)x >> 56) & 0x00000000000000ffLL)))

typedef uint32_t FOURCC;
typedef uint32_t DWORD;
typedef uint16_t WORD;
typedef int32_t SDWORD;
typedef int16_t SHORT;

//void Swap32(unsigned int * inUInt32);

typedef struct
{
	unsigned int	dwSize;
	unsigned int	fcc;		/* mdat */
} box_header_t;

typedef struct {
	unsigned int	size;       // [0]
	unsigned int	fcc;    // [4]
/*
	unsigned char	version[1]; //[8]
	unsigned char	flags[3];   //[9]
	unsigned int	creation_time;//[12]
	unsigned int	modification_time;//[16]
*/
	unsigned int	timescale;//[20]
	unsigned int	duration;//[24]
/*
	unsigned int	rate;//[28]
	unsigned short	volume;//[32]
	unsigned char	reserved[10];//[34]
	unsigned char	matrix[36];//[44]
	unsigned char	pre_defined[24];//[80]
*/
	unsigned int	next_track_id; //[104] total 108 bytes
} MVHDBox;


typedef struct {
	unsigned int	size;       // [0]
	unsigned int	fcc;    // [4]

} MP4MVHD;

typedef struct {
	unsigned int	size; //[0]
	unsigned int	fcc; //[4]
/*
	unsigned char	version[1];//[8]
	unsigned char	flags[3];//[9]
	unsigned int	creation_time;//[12]
	unsigned int	modification_time;//[16]
*/
	unsigned int	trackid;//[20]
/*
	unsigned char	reserved0[4];//[24]
	unsigned int	duration;//[28]
	unsigned char	reserved1[8];//[32]
	unsigned short	layer;//[40]
	unsigned short	alternate_group;//[42]
	unsigned short	volume;//[44]
	unsigned char	reserved2[2];//[46]
	unsigned char	matrix[36];//[48]
*/

	unsigned int	width;//[84]
	unsigned int	height;//[88] total 92 bytes

} MP4TKHD;


typedef struct {
	unsigned int	size;
	unsigned int	fcc;
/*
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	creation_time;
	unsigned int	modification_time;
*/
	unsigned int	timescale;
	unsigned int	duration;
/*
	unsigned short	language;
	unsigned short	quality;
*/
} MP4MDHD;


typedef struct {
	unsigned int	size;
	unsigned int	fcc;
/*
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	pre_defined;
	unsigned char	handler_type[4]; // vide
	unsigned int	reserved[3];
*/
} MP4HDLR;

typedef struct {
	unsigned int	size;
	unsigned int	fcc;
} MINFBox;

typedef struct {
	unsigned int	size;
	unsigned int	fcc;
} MP4VMHD;

typedef struct {
	unsigned int	size;
	unsigned int	fcc;
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned short	balance;
	unsigned char	reversed[2];
} MP4SMHD;

typedef struct {
	unsigned int	size;
	unsigned int	fcc;
} MP4DINF;

typedef struct {
	/*unsigned int	size;
	unsigned int fcc;*/
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	entry_count;
    unsigned short  channel_count;
    unsigned int    sample_rate;
    char    *vps;
    char    length_of_vps;
    char    *sps;
    char    length_of_sps;
    char    *pps;
    char    length_of_pps;
} MP4STSD;

typedef struct {
	unsigned int	sec;
	unsigned int	usec;
} MP4Time;

typedef struct {
	/*unsigned int	size;
	unsigned int fcc;*/
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	entry_count;
	unsigned int    *sample_count;
    unsigned int	*sample_delta;
} MP4STTS;

typedef struct {
	/*unsigned int	size;
	unsigned int fcc;*/
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	entry_count;
	unsigned int	*sample_number; //frame number of a key frame
} MP4STSS;

typedef struct {
	/*unsigned int	size;
	unsigned int fcc;*/
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	sample_size;
	unsigned int	entry_count;
	unsigned int 	*single_sample_size;
} MP4STSZ;

typedef struct {
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	entry_count;
    unsigned int	*first_chunk;
    unsigned int	*samples_per_chunk;
//    unsigned int *stsd_id;
} MP4STSC;

typedef struct {
	/*unsigned int	size;
	unsigned int fcc;*/
	unsigned char	version[1];
	unsigned char	flags[3];
	unsigned int	entry_count;
	unsigned long long	*chunk_offset;
} MP4STCO;


typedef struct {
	unsigned int	size;
	unsigned int	fcc; //stbl

	MP4STSD		*stsd;

	MP4STTS		*stts;
    MP4STSS     *stss;
	MP4STSC		*stsc;
	MP4STSZ		*stsz;

	MP4STCO		*stco;

} MP4STBL;


typedef struct {
	MP4STBL		stbl;
} MP4MINF;


typedef struct {
	unsigned int	size;
	unsigned int	fcc; //"mdia"
	MP4MDHD			mdhd;
	box_header_t	hdlr;
    unsigned int	handler_type;
	MP4MINF			minf;
} MP4MDIA;


typedef struct {
	box_header_t trakbox;
	MP4TKHD		tkhd;

	box_header_t edts;

	MP4MDIA		mdia;
} MP4TRAK;

typedef struct
{
	DWORD			size;
	unsigned int	fcc;		/* moov */

    MVHDBox			mvhd;
	unsigned int	editing_track_id;
	unsigned int	trak_count;
	MP4TRAK			trak[2];

} mp4_moov_header_t;

#ifdef __cplusplus
}
#endif

#endif

