//**************************************************************************
//*                     This file is part of the                           *
//*                    Mpxplay-MMC - video player.                         *
//*                The source code of Mpxplay-MMC is                       *
//*        (C) copyright 1998-2018 by PDSoft (Attila Padar)                *
//*                http://mpxplay.sourceforge.net                          *
//*                  email: mpxplay@freemail.hu                            *
//**************************************************************************
//*  This program is distributed in the hope that it will be useful,       *
//*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *
//*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                  *
//*  Please contact with the author (with me) if you want to use           *
//*  or modify this source.                                                *
//**************************************************************************
//function: digital TV (DVB) handling by BDA driver

#ifndef DTV_DRV_H
#define DTV_DRV_H

#include "diskdriv.h"

#ifdef __cplusplus
extern "C" {
#endif

#define DTVBDA_FEC(a,b)   (((a) << 16u) | (b))
#define DTVBDA_FEC_AUTO   0xFFFFFFFF
#define DTVDBA_GUARD(a,b) (((a) << 16u) | (b))
#define DTVDBA_GUARD_AUTO 0xFFFFFFFF

enum {
	BDADEVTYPE_ATSC   = 0x00000001,
	BDADEVTYPE_CQAM   = 0x00000002,

	BDADEVTYPE_DVB_C  = 0x00000010,
	BDADEVTYPE_DVB_C2 = 0x00000020,
	BDADEVTYPE_DVB_S  = 0x00000040,
	BDADEVTYPE_DVB_S2 = 0x00000080,
	BDADEVTYPE_DVB_T  = 0x00000100,
	BDADEVTYPE_DVB_T2 = 0x00000200,

	BDADEVTYPE_ISDB_C = 0x00001000,
	BDADEVTYPE_ISDB_S = 0x00002000,
	BDADEVTYPE_ISDB_T = 0x00004000,
};

#define MPXPLAY_DRVDTV_DEFAULT_TIMEOUTMS_OPENSHOWSIGSTR_100  5000 // show signal strength at opening a new freq/device till 5 secs (even if the signal strength is high)
#define MPXPLAY_DRVDTV_DEFAULT_TIMEOUTMS_OPENSHOWSIGSTR_60  15000 // show signal strength if it's less or equal than 60 (usually bellow 60, the playing will not correct)
#define MPXPLAY_DRVDTV_DEFAULT_TIMEOUTMS_READ   6000
#define MPXPLAY_DRVDTV_DEFAULT_TIMEOUTMS_MUTEX  6000

#define MPXPLAY_DRVDTV_INITIAL_CONTINUITY_LIMIT 3 // initial error detection in frames

#define MPXPLAY_DRVDTV_FLAG_TERMINATE     (1 << 0)
#define MPXPLAY_DRVDTV_FLAG_READWAIT      (1 << 1)
#define MPXPLAY_DRVDTV_FLAG_OPENMODE_PLAY (1 << 2)

enum {DTVBDA_DATABUF_BUFTYPE_MULTIPLEX = 0, DTVBDA_DATABUF_BUFTYPE_PROGRAM};

#define DTVBDA_DATABUF_INITSIZE_PROG 1048576
#define DTVBDA_DATABUF_INITSIZE_MUX (1048576 * 10)

// dtvbda_data_buffer_s buffer_flags
#define DTVBDA_DATABUF_FLAGCTR_OPENMODE_PLAY      (1 << 0) // buffer is used for play (not for copy)
#define DTVBDA_DATABUF_FLAGCTR_READLOCK           (1 << 1) // lock for read (delayed read, detect possible initial stream errors)
#define DTVBDA_DATABUF_FLAGINF_ERROR_CONTINUITY   (1 << 8) // lost blocks (by device)
#define DTVBDA_DATABUF_FLAGINF_ERROR_BUFFER_FULL  (1 << 9) // buffer became full
#define DTVBDA_DATABUF_FLAGINF_MASK               0xff00

typedef struct dtvresource_chainelem_s dtvresource_chainelem_t;
typedef struct dvb_device_s dvb_device_t;

typedef struct dtvbda_data_buffer_s
{
    mpxp_uint8_t *buffer_beginptr;
    int buffer_size;
    int buffer_putpos;
    int buffer_getpos;
    int buffer_rewindbytes;        // buffered and read bytes, we should use it at MUX buffer only
    int buffer_forwardbytes;       // buffered but not read bytes
    unsigned int buffer_type;      // DTVBDA_DATABUF_BUFTYPE_MULTIPLEX or program number if > 0
    unsigned int buffer_flags;     // DTVBDA_DATABUF_FLAGINF_
    struct dtvbda_data_buffer_s *prev_databuffer;
    struct dtvbda_data_buffer_s *next_databuffer;
    dvb_device_t *dev_ptr;
}dtvbda_data_buffer_s;

typedef struct dvb_device_s
{
	mpxp_uint32_t flags;
	mpxp_uint32_t protocol_number_id;
	dtvresource_chainelem_t *dtv_resource;
    void *bdagraph_module;
    dtvbda_data_buffer_s *data_buffer;

    mpxp_int32_t adapter_num;
    mpxp_int32_t frequency;
    mpxp_int32_t program_number_id;    // DTVBDA_DATABUF_BUFTYPE_MULTIPLEX or program number if > 0

    /* DVB-S */
    mpxp_int32_t srate;
    mpxp_int32_t fec;
    mpxp_int32_t inversion;
    char lnb_polarization;
    mpxp_int32_t lowf, highf, switchf;
    mpxp_int32_t azimuth, elevation, longitude, network_id;
    char *mod, *range, *network_name;

    /* DVB-T */
    mpxp_int32_t fec_hp, fec_lp, bandwidth;
    mpxp_int32_t guard;
    mpxp_int32_t transmission;
    mpxp_int32_t hierarchy;

    /* ATSC, CQAM */
    mpxp_int32_t physical_channel, major_channel, minor_channel;

    mpxp_int64_t timeout_at_read;
    mpxp_int64_t timeout_open_showsignalstrength;
}dvb_device_t;

typedef struct dtvresource_chainelem_s
{
	struct dtvresource_chainelem_s *prev_res;
	struct dtvresource_chainelem_s *next_res;
	dvb_device_t dev_infos;
}dtvresource_chainelem_t;

extern dvb_device_t *dtv_bda_device_alloc(void);
extern int dtv_bda_resource_assign(dvb_device_t *dtv_device);
extern int dtv_bda_resource_remove(dvb_device_t *dtv_device);
extern void dtv_bda_device_free(dvb_device_t *d);
extern int dtv_bda_device_read(dvb_device_t *d, char *buf, int requested_bytes);
extern int dtv_bda_device_get_signal_strength(dvb_device_t *d);

# ifdef __cplusplus
}
# endif

#endif // DTV_DRV_H
