/***************************************************************************************
 *
 *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
 *
 *  By downloading, copying, installing or using the software you agree to this license.
 *  If you do not agree to this license, do not download, install, 
 *  copy or use the software.
 *
 *  Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
 *
 *  Redistribution and use in binary forms, with or without modification, are permitted.
 *
 *  Unless required by applicable law or agreed to in writing, software distributed 
 *  under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 *  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
 *  language governing permissions and limitations under the License.
 *
****************************************************************************************/

#ifndef HTTP_FLV_CLN_H
#define HTTP_FLV_CLN_H

#include "rtmp.h"
#include "http.h"


#define HTTP_FLV_EVE_STOPPED    80
#define HTTP_FLV_EVE_CONNECTING 81
#define HTTP_FLV_EVE_CONNFAIL   82
#define HTTP_FLV_EVE_NOSIGNAL   83
#define HTTP_FLV_EVE_RESUME     84
#define HTTP_FLV_EVE_AUTHFAILED 85
#define HTTP_FLV_EVE_NODATA   	86
#define HTTP_FLV_EVE_VIDEOREADY 87
#define HTTP_FLV_EVE_AUDIOREADY 88

#define HTTP_FLV_RX_FAIL        -1
#define HTTP_FLV_RX_TIMEOUT     1
#define HTTP_FLV_RX_SUCC        2

typedef int (*http_flv_notify_cb)(int, void *);
typedef int (*http_flv_video_cb)(uint8 *, int, uint32, void *);
typedef int (*http_flv_audio_cb)(uint8 *, int, uint32, void *);


class CHttpFlvClient
{
public:
	CHttpFlvClient(void);
	~CHttpFlvClient(void);

public:
	BOOL    http_flv_start(const char * url, const char * user, const char * pass);
	BOOL    http_flv_play();
	BOOL    http_flv_stop();
	BOOL    http_flv_pause();
	BOOL    http_flv_close();

    char *  get_url() {return m_url;}
	char *  get_user() {return m_user;}
	char *  get_pass() {return m_pass;}
    int     audio_codec() {return m_nAudioCodec;}
	int     video_codec() {return m_nVideoCodec;}
	void 	get_h264_params();
	BOOL 	get_h264_params(uint8 * p_sps, int * sps_len, uint8 * p_pps, int * pps_len);
	void    get_h265_params();
    BOOL    get_h265_params(uint8 * p_sps, int * sps_len, uint8 * p_pps, int * pps_len, uint8 * p_vps, int * vps_len);
	int     get_video_width() {return m_nWidth;}
	int     get_video_height() {return m_nHeight;}
	double  get_video_framerate() {return m_nFrameRate;}
	int     get_audio_samplerate() {return m_nSamplerate;}
	int     get_audio_channels() {return m_nChannels;}
	uint8 * get_audio_config() {return m_pAudioConfig;}
	int     get_audio_config_len() {return m_nAudioConfigLen;}
	uint32  get_video_init_ts() {return m_nVideoInitTS;}
	uint32  get_audio_init_ts() {return m_nAudioInitTS;}
	
    void    set_notify_cb(http_flv_notify_cb notify, void * userdata);
    void    set_video_cb(http_flv_video_cb cb);
    void    set_audio_cb(http_flv_audio_cb cb);
    void    set_rx_timeout(int timeout);

    void    rx_thread();
    void    http_flv_video_data_cb(uint8 * p_data, int len, uint32 ts);
    void    http_flv_audio_data_cb(uint8 * p_data, int len, uint32 ts);
        
private:
    BOOL    http_flv_req(HTTPREQ * p_http);
    BOOL    http_flv_connect();
    int     http_flv_h264_rx(uint8 * data, uint32 size, uint32 ts);
    int     http_flv_h265_rx(uint8 * data, uint32 size, uint32 ts);
    int     http_flv_video_rx(uint8 * data, uint32 size, uint32 ts);
    int     http_flv_g711_rx(uint8 * data, uint32 size, uint32 ts);
    int     http_flv_aac_rx(uint8 * data, uint32 size, uint32 ts);
    int     http_flv_audio_rx(uint8 * data, uint32 size, uint32 ts);
    int     http_flv_metadata_rx(uint8 * data, uint32 size);
    BOOL    http_flv_res_rx(HTTPREQ * p_http);
    BOOL    http_flv_data_handler(HTTPREQ * p_http);
    BOOL    http_flv_header_rx(HTTPREQ * p_http);
    BOOL    http_flv_chunked(HTTPREQ * p_http);
    BOOL    http_flv_data_rx(HTTPREQ * p_http);
    int     http_flv_rx(HTTPREQ * p_http);
    void    http_flv_send_notify(int event);
    
private:
    char            m_url[512];
    char            m_user[64];
    char            m_pass[64];
    
    HTTPREQ         m_http;
    BOOL            m_bRunning;
    BOOL            m_bVideoReady;
    BOOL            m_bAudioReady;
    BOOL            m_bChunked;
    BOOL            m_bFlvHeader;
    pthread_t       m_tidRx;
    
    uint8           m_pVps[256];
	int	            m_nVpsLen;
    uint8           m_pSps[256];
	int	            m_nSpsLen;
	uint8           m_pPps[256];
	int	            m_nPpsLen;
	
    uint8           m_pAudioConfig[32];
	uint32          m_nAudioConfigLen;

    int		        m_nVideoCodec;
    int             m_nWidth;
    int             m_nHeight;
    double          m_nFrameRate;
	int     		m_nAudioCodec;
	int             m_nSamplerate;
	int             m_nChannels;

    uint32          m_nVideoInitTS;
	uint32          m_nAudioInitTS;
	
    http_flv_notify_cb  m_pNotify;
	void *              m_pUserdata;
	http_flv_video_cb   m_pVideoCB;
	http_flv_audio_cb   m_pAudioCB;
	void *              m_pMutex;
	int                 m_nRxTimeout;
};

#endif




