/* -*- tab-width: 4; indent-tabs-mode: nil -*- */
#ifndef _RECPT1_H_
#define _RECPT1_H_
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "decoder.h"
#include "tssplitter_lite.h"

#define HAVE_LIBARIB25 1
#define NUM_BSDEV       8
#define NUM_ISDB_T_DEV  8
#define CHTYPE_SATELLITE    0        /* satellite digital */
#define CHTYPE_GROUND       1        /* terrestrial digital */
#define MAX_QUEUE           8192
#define MAX_READ_SIZE       (188 * 87) /* 188*87=16356 splitterが188アライメントを期待しているのでこの数字とする*/
#define WRITE_SIZE          (1024 * 1024 * 2)
#define TRUE                1
#define FALSE               0
#define STREAM_MAX (16)


/* type definitions */
typedef int boolean;

typedef struct _BUFSZ {
    int size;
    u_char buffer[MAX_READ_SIZE];
} BUFSZ;

typedef struct _QUEUE_T {
    unsigned int in;        // 次に入れるインデックス
    unsigned int out;        // 次に出すインデックス
    unsigned int size;        // キューのサイズ
    unsigned int num_avail;    // 満タンになると 0 になる
    unsigned int num_used;    // 空っぽになると 0 になる
    pthread_mutex_t mutex;
    pthread_cond_t cond_avail;    // データが満タンのときに待つための cond
    pthread_cond_t cond_used;    // データが空のときに待つための cond
    BUFSZ *buffer[1];    // バッファポインタ
} QUEUE_T;

typedef struct _STREAM_QUEUE_T {
    unsigned int in;        // 次に入れるインデックス
    unsigned int out;        // 次に出すインデックス
    unsigned int size;        // キューのサイズ
    unsigned int num_avail;    // 満タンになると 0 になる
    unsigned int num_used;    // 空っぽになると 0 になる
    pthread_mutex_t mutex;
    pthread_cond_t cond_avail;    // データが満タンのときに待つための cond
    pthread_cond_t cond_used;    // データが空のときに待つための cond
    ARIB_STD_B25_BUFFER   *buffer[1];    // バッファポインタ
} STREAM_QUEUE_T;

typedef struct _ISDB_T_FREQ_CONV_TABLE {
    int set_freq;    // 実際にioctl()を行う値
    int type;        // チャンネルタイプ
    int add_freq;    // 追加する周波数(BS/CSの場合はスロット番号)
    char *parm_freq;    // パラメータで受ける値
} ISDB_T_FREQ_CONV_TABLE;

typedef struct sock_data {
    int sfd;    /* socket fd */
    struct sockaddr_in addr;
} sock_data;

typedef struct _session {
    int id;
    int is_valid;
    QUEUE_T *p_queue;
} session;

typedef struct _streamer {
    pthread_mutex_t mutex;   //open、close、(recpt1からの)write
    int stream_nr;
    size_t total_byte; // 送信BYTE数
    struct timespec start; // 開始時刻
    session *stream_session[STREAM_MAX]; //NULL止めの配列
} streamer;

typedef struct thread_data {
    QUEUE_T *queue;
    QUEUE_T *stream_queue;
    decoder *decoder;
    decoder_options *dopt;
    int ch;
    int lnb;    /* LNB voltage */
    int tfd;    /* tuner fd */
    int wfd;    /* output file fd */
    int device_id; /* /dev/pt1video[N] */
    ISDB_T_FREQ_CONV_TABLE *table;
    sock_data *sock_data;
    pthread_t signal_thread;
    int recsec;
    time_t start_time;
    boolean indefinite;
    int msqid;
    splitter *splitter;
    streamer *streamer;
} thread_data;

QUEUE_T *create_queue(size_t size);
BUFSZ * dequeue(QUEUE_T *p_queue);
void destroy_queue(QUEUE_T *p_queue);
void destroy_stream_queue(STREAM_QUEUE_T *p_queue);

#endif
