/* mpegts.h
 * mpeg-ts muxer
 * Copyright (c) 2010-2025 Sensoray Co., Inc.
 * authors: D.A. P.E.
 */

#ifndef MPEGTS_H
#define MPEGTS_H

#define REGISTRATION_DESCRIPTOR_NONE  0
#define REGISTRATION_DESCRIPTOR_BSSD  1

typedef struct tsmuxer {
    struct {
        unsigned int  PID;      // video=0x1011 audio=0x1100
        unsigned char type;     // stream type, use TS_TYPE_* below
        unsigned char profile_idc;
        unsigned char level_idc;
        unsigned char priority; // transport priority bit
        unsigned int  cur_PTS;
        unsigned int  last_PTS;
        unsigned char last_PTS_MSB; //33rd bit
        unsigned int  cur_DTS;
        unsigned int  last_DTS;
        unsigned char last_DTS_MSB; //33rd bit
        unsigned int  PES_length;
        unsigned int  PES_length_actual;
        unsigned int  read_offset; // tsmux_read
        unsigned int  frame;
	unsigned int  cc_error; // total number of continuity count errors
        unsigned char cc;
	unsigned char PES_stream_id;  // video=0xe0 audio=0xa0 private(PCM)=0xbd
	    unsigned int registration_descriptor; // 0 for none
        unsigned char rd_format_identifier[4]; // in registration descriptor
	    int framing_index;
    } audio, video, priv;
    unsigned int  program_number;
    unsigned int  program_PID; // PMT
    unsigned int  PCR_PID;
    unsigned int  cur_PCR;
    unsigned int  last_PCR;
    unsigned char last_PCR_MSB; //33rd bit
    unsigned int  last_NIT;
    unsigned int  last_PAT;
    unsigned int  scan_offset; // tsmux_scan
    unsigned char enable_NIT;

    unsigned char PAT_cc;
    unsigned char PMT_cc;
    unsigned char PCR_cc;
    unsigned char NIT_cc;
    unsigned char PCR_discontinuity_indicator;
    unsigned char program_stream;
    unsigned char scan_whole_frame;  // always at least one frame sent per tsmux_scan

    unsigned char PSTD_header_done;
    unsigned char LPCM_mode;
    unsigned char LPCM_frame;
    unsigned int LPCM_offset;

    char *PCR_log; // message to be embedded in PCR packets (up to 176 bytes)

    unsigned long pos;
    unsigned char *buf; // used by tsmux_read
    unsigned char *dump_dest; // used by tsmux_read
    unsigned int dump_len; // used by tsmux_read
    unsigned int dump_PID; // used by tsmux_read
} *tsmux_handle;

extern tsmux_handle tsmux_create(void);
extern void tsmux_delete(tsmux_handle);

extern unsigned int tsmux_write(tsmux_handle, unsigned int PID, unsigned char *dest, unsigned char *src, unsigned int len);

/* scan a buffer for a complete PES packet, and return its PID when found, else 0 */
extern unsigned int tsmux_scan(tsmux_handle, unsigned char *src, unsigned int len);

/* read a complete PES packet from a specific PID into dest, returns PES packet length */
extern unsigned int tsmux_read(tsmux_handle, unsigned int PID, unsigned char *dest, unsigned char *src, unsigned int len);

extern int tsmux_setup_pcm(tsmux_handle, int sample_rate, int channels, int bitspersample);

#define TS_TYPE_MPEG2_VIDEO 0x02
#define TS_TYPE_MPEG4_VIDEO 0x10
#define TS_TYPE_H264_VIDEO 0x1b
#define TS_TYPE_AAC_AUDIO 0x0f
#define TS_TYPE_PCM_AUDIO 0x06 //0xa0 // 0xa0 MSCODEC Video.
#define TS_TYPE_MP3_AUDIO 0x03

#endif // MPEGTS_H
