/**
 * @brief           Movie Player Sample データ型
 * @author          AXELL CORPORATION
 * @history         2017_02_22  初版
 * @history         2017_10_26  Ver2.0
 * @history         2019_03_08  [SDK2.2] MPSでのGVDサーチレンジの設定によってデコーダが終了しなくなる不具合等を修正 (#2449)
 * @description     MPSのマクロ、データ型定義
 * @note            エラーコードはAG903_error.hを参照のこと.
 */

/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2019 AXELL CORPORATION, all rights reserved.
 */

/* DOM-IGNORE-BEGIN */
#ifndef __MPS_TYPE_H_
#define __MPS_TYPE_H_
/* DOM-IGNORE-END */

#include <stdint.h>
#include <gvd/gvd.h>
#include <AG903_errno.h>

/** ファイル名の最大長 */
#define MPS_MAX_FILENAME_LENGTH 256

/** ボックスタイプ 'mdat' */
#define MPS_BOX_TYPE_MDAT (0x6D646174)
/** ボックスタイプ 'moov' */
#define MPS_BOX_TYPE_MOOV (0x6D6F6F76)
/** ボックスタイプ 'mvhd' */
#define MPS_BOX_TYPE_MVHD (0x6D766864)
/** ボックスタイプ 'trak' */
#define MPS_BOX_TYPE_TRAK (0x7472616B)
/** ボックスタイプ 'mdia' */
#define MPS_BOX_TYPE_MDIA (0x6D646961)
/** ボックスタイプ 'mdhd' */
#define MPS_BOX_TYPE_MDHD (0x6D646864)
/** ボックスタイプ 'minf' */
#define MPS_BOX_TYPE_MINF (0x6D696E66)
/** ボックスタイプ 'stbl' */
#define MPS_BOX_TYPE_STBL (0x7374626C)
/** ボックスタイプ 'stsd' */
#define MPS_BOX_TYPE_STSD (0x73747364)
/** ボックスタイプ 'avc1' */
#define MPS_BOX_TYPE_AVC1 (0x61766331)
/** ボックスタイプ 'avcC' */
#define MPS_BOX_TYPE_AVCC (0x61766343)
/** ボックスタイプ 'stts' */
#define MPS_BOX_TYPE_STTS (0x73747473)
/** ボックスタイプ 'stss' */
#define MPS_BOX_TYPE_STSS (0x73747373)
/** ボックスタイプ 'stsc' */
#define MPS_BOX_TYPE_STSC (0x73747363)
/** ボックスタイプ 'stsz' */
#define MPS_BOX_TYPE_STSZ (0x7374737A)
/** ボックスタイプ 'stco' */
#define MPS_BOX_TYPE_STCO (0x7374636F)

/** avc1先頭からavcCのオフセット */
#define MPS_BOX_AVCC_OFFSET_FROM_AVC1 86

/** MPSの初期化パラメータ */
typedef struct
{
    uint32_t max_stream;                /** 最大同時再生ストリーム数 */
    uint32_t stream_buffer_size;        /** ストリームバッファサイズ */
    uintptr_t stream_buffer_num;        /** ストリームバッファ数 */
    gvdCbFunc func_decode_done_handler; /** デコード完了コールバックハンドラ */
	gvdCbFunc func_fatalerror_handler; /** 致命的エラーコールバックハンドラ */
}mpsSetting;

/** GVDの初期化パラメータ */
typedef struct
{
    void *memory_work_top;             /** GVDワークRAM領域先頭アドレス */
    uint32_t memory_work_size;         /** GVDワークRAM領域サイズ<p> \
									       参照:MPS_GetRequiredWorkMemorySize */
    void *memory_heap_top;             /** GVDヒープRAM領域先頭アドレス */
    uint32_t memory_heap_size;         /** GVDヒープRAM領域サイズ */
    gvdOutMod output_select;           /** GVD出力先選択 */
    uint32_t num_out_buffer;           /** 出力バッファの段数 */
}mpsConfig;

/** 非同期処理用フラグ */
typedef struct
{
    bool bInitialized;     /** 初期化完了フラグ */
    bool bParsed;          /** MP4コンテナ解析完了フラグ */
    bool bOpened;          /** オープン処理完了フラグ */
    bool bPlayAccepted;    /** 再生受付フラグ */
    bool bPaused;          /** 一時停止フラグ */
    bool bSought;          /** シーク完了フラグ */
    bool bRewindAccepted;  /** 早戻し受付フラグ */
    bool bRewindDone;      /** 早戻し完了フラグ */
    bool bForwardAccepted; /** 早送り受付フラグ */
    bool bDecDone;         /** デコード完了フラグ */
    bool bClosed;          /** クローズ処理完了フラグ */
    bool bFinalized;       /** 終了処理完了フラグ */
}mpsAsyncFlag;

/** MP4コンテナ情報 */
typedef struct
{
    uint32_t profile;        /** H.264 プロファイル */
    uint32_t level;          /** H.264 レベル */
    uint32_t total_frame;    /** 総フレーム数 */
    uint32_t height;         /** フレーム高さ[pixel] */
    uint32_t width;          /** フレーム幅[pixel] */
    uint32_t stream_size;    /** ストリームサイズ[Byte] */
    uint32_t time_scale;     /** サンプリング周波数 (mdhd) */
    uint32_t duration;       /** 長さ[sample] (mdhd) */
    uint32_t frame_length;   /** フレーム再生間隔[ms] (stts) */
    uint32_t max_ref_frames; /** 最大参照フレーム数 (avcC) */
    uint32_t keyframe_count; /** IDRフレーム数 (stss) */
    uint32_t *keyframe;      /** IDRフレームリスト (stss) */
    uint32_t position_count; /** 位置情報バッファ要素数 */
    gvdPositionBuffer *position_buf;  /** 位置情報バッファ(GVD用) */
}mpsMovieInfo;

/** コンテキスト情報 */
typedef struct
{
    int32_t id;         /** コンテキストID */
    int32_t *fp;        /** ファイルポインタ */
    uint32_t filesize;  /** ファイルサイズ */
    gvdContext *gvdctx; /** GVDコンテキスト構造体 */
    mpsAsyncFlag flag;  /** 非同期処理系フラグ群 */
    mpsMovieInfo info;  /** 動画ファイル情報構造体 */
    char filename[MPS_MAX_FILENAME_LENGTH]; /** ファイルパス */
}mpsContext;

/** Boxオフセット情報 */
typedef struct
{
    uint32_t mdat; /** stream data */
    uint32_t mvhd; /** ms-unit duration(for sync?) */
    uint32_t mdhd; /** timescale, duration */
    uint32_t avc1; /** width, height */
    uint32_t avcC; /** profile, level, refs */
    uint32_t stts; /** frame length[sample] */
    uint32_t stss; /** IDR-Frame numbers */
    uint32_t stsc; /** chunk info */
    uint32_t stsz; /** sample size */
    uint32_t stco; /** chunk offset */
}mpsInfoPos;

/** フレーム番号とストリーム位置の対応情報 */
typedef struct
{
    uint32_t frame_id; /** フレーム番号 */
    uint32_t pos;      /** ストリームオフセット */
}mpsFramePos;

/** 出力バッファ情報 */
typedef gvdOutBufInfo mpsOutBufInfo;

/** シーク種別 */
typedef enum {
    MPS_SEEK_INDEX,          /** 位置情報単位 */
    MPS_SEEK_RELATIVE_INDEX, /** 位置情報単位（相対） */
    MPS_SEEK_FRAME,          /** フレーム単位 */
    MPS_SEEK_TIME,           /** 時間単位 */
}mpsSeekMode;

/** AVCヘッダ情報 */
typedef struct
{
    uint32_t size; /** dataのサイズ */
    uint8_t *data; /** ヘッダ */
}mpsAVCHeader;

#endif /* __MPS_TYPE_H_ */
