/* * MPEG-2 transport stream defines * Copyright (c) 2003 Fabrice Bellard * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg 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. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef AVFORMAT_MPEGTS_H #define AVFORMAT_MPEGTS_H #include "libavformat/avformat.h" #include "libavformat/aml/utils/ffmpegObMsgheader.h" #define TS_FEC_PACKET_SIZE 204 #define TS_DVHS_PACKET_SIZE 192 #define TS_PACKET_SIZE 188 #define TS_MAX_PACKET_SIZE 204 #define NB_PID_MAX 8192 #define MAX_SECTION_SIZE 4096 /* pids */ #define PAT_PID 0x0000 #define CAT_PID 0x0001 #define SDT_PID 0x0011 /* table ids */ #define PAT_TID 0x00 #define CAT_TID 0x01 #define PMT_TID 0x02 #define M4OD_TID 0x05 #define SDT_TID 0x42 #define STREAM_TYPE_VIDEO_MPEG1 0x01 #define STREAM_TYPE_VIDEO_MPEG2 0x02 #define STREAM_TYPE_AUDIO_MPEG1 0x03 #define STREAM_TYPE_AUDIO_MPEG2 0x04 #define STREAM_TYPE_PRIVATE_SECTION 0x05 #define STREAM_TYPE_PRIVATE_DATA 0x06 #define STREAM_TYPE_AUDIO_AAC 0x0f #define STREAM_TYPE_AUDIO_AAC_LATM 0x11 #define STREAM_TYPE_VIDEO_MPEG4 0x10 #define STREAM_TYPE_METADATA 0x15 #define STREAM_TYPE_VIDEO_H264 0x1b #define STREAM_TYPE_VIDEO_HEVC 0x24 #define STREAM_TYPE_VIDEO_CAVS 0x42 #define STREAM_TYPE_VIDEO_VC1 0xea #define STREAM_TYPE_VIDEO_DIRAC 0xd1 #define STREAM_TYPE_AUDIO_AC3 0x81 #define STREAM_TYPE_AUDIO_DTS 0x82 #define STREAM_TYPE_AUDIO_TRUEHD 0x83 #define STREAM_TYPE_AUDIO_EAC3 0x87 #include "libavutil/opt.h" typedef struct MpegTSContext MpegTSContext; typedef struct MpegTSFilter MpegTSFilter; enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, MPEGTS_PCR, }; typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos); typedef void SectionCallback(MpegTSFilter *f, const uint8_t *buf, int len); typedef void (*ffmpegts_notify_t)(void *handle, int msg, int64_t ext1, int64_t ext2, int64_t ext3); typedef struct MpegTSPESFilter { PESCallback *pes_cb; void *opaque; } MpegTSPESFilter; typedef struct MpegTSSectionFilter { int section_index; int section_h_size; int last_ver; unsigned crc; unsigned last_crc; uint8_t *section_buf; unsigned int check_crc : 1; unsigned int end_of_section_reached : 1; SectionCallback *section_cb; void *opaque; } MpegTSSectionFilter; struct MpegTSFilter { int pid; int es_id; int last_cc; /* last cc code (-1 if first packet) */ int64_t last_pcr; enum MpegTSFilterType type; union { MpegTSPESFilter pes_filter; MpegTSSectionFilter section_filter; } u; }; struct MpegTSContext { const AVClass *clasz; /* user data */ AVFormatContext *stream; /** raw packet size, including FEC if present */ int raw_packet_size; int size_stat[3]; int size_stat_count; #define SIZE_STAT_THRESHOLD 10 int64_t pos47_full; /** if true, all pids are analyzed to find streams */ int auto_guess; /** compute exact PCR for each transport stream packet */ int mpeg2ts_compute_pcr; /** fix dvb teletext pts */ int fix_teletext_pts; int64_t cur_pcr; /**< used to estimate the exact PCR */ int pcr_incr; /**< used to estimate the exact PCR */ /* data needed to handle file based ts */ /** stop parsing loop */ int stop_parse; /** packet containing Audio/Video data */ AVPacket *pkt; /** to detect seek */ int64_t last_pos; int skip_changes; int skip_clear; int scan_all_pmts; int resync_size; /******************************************/ /* private mpegts data */ /* scan context */ /** structure to keep track of Program->pids mapping */ unsigned int nb_prg; struct Program *prg; int8_t crc_validity[NB_PID_MAX]; /** filters for various streams specified by PMT + for the PAT and PMT */ MpegTSFilter *pids[NB_PID_MAX]; int current_pid; void *session; int transport_scrambling_control; int ca_system_id; int emm_pid;/*pid for EMM*/ uint8_t *cat_section_data;/*cat section data*/ int cat_data_len;/*cat section data length*/ int* dvb_audio_preselection_idxs; unsigned int nb_audio_preselection_idxs; unsigned char* dvb_audio_preselection; unsigned int dvb_audio_preselection_length; int page_number; int magazine_number; ffmpegts_notify_t mpegts_notify; ffmpegts_notify_t parent_notify; }; ///////////////////////// #define MAX_RESYNC_SIZE 65536 #define MPEGTS_OPTIONS \ { \ "resync_size", "set size limit for looking up a new synchronization", offsetof(MpegTSContext, resync_size), AV_OPT_TYPE_INT, {.i64 = MAX_RESYNC_SIZE}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM \ } /////////////////////// static const AVOption aml_mpegts_options[] = { MPEGTS_OPTIONS, {"fix_teletext_pts", "try to fix pts values of dvb teletext streams", offsetof(MpegTSContext, fix_teletext_pts), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_DECODING_PARAM}, {"ts_packetsize", "output option carrying the raw packet size", offsetof(MpegTSContext, raw_packet_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY}, {"scan_all_pmts", "scan and combine all PMTs", offsetof(MpegTSContext, scan_all_pmts), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM}, {"skip_changes", "skip changing / adding streams / programs", offsetof(MpegTSContext, skip_changes), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0}, {"skip_clear", "skip clearing programs", offsetof(MpegTSContext, skip_clear), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, 0}, {"ca_system_id", "id for dvb ca system", offsetof(MpegTSContext, ca_system_id), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 0, AV_OPT_FLAG_EXPORT}, {"emm_pid", "pid for EMM", offsetof(MpegTSContext, emm_pid), AV_OPT_TYPE_INT, {.i64 = 0x1fff}, 0, 0x1fff, AV_OPT_FLAG_EXPORT}, {"transport_scrambling_control", "transport_scrambling_control", offsetof(MpegTSContext, transport_scrambling_control), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 3, AV_OPT_FLAG_EXPORT}, {"cat_section_data", "cat section data", offsetof(MpegTSContext, cat_section_data), AV_OPT_TYPE_BINARY, 0, 0, AV_OPT_FLAG_EXPORT}, {"dvb_audio_preselection", "EXT DESCRIPTOR DVB AUDIO PRESELECTION", offsetof(MpegTSContext, dvb_audio_preselection), AV_OPT_TYPE_BINARY, 0, 0, AV_OPT_FLAG_EXPORT}, {"dvb_audio_preselection_length", "EXT DESCRIPTOR DVB AUDIO PRESELECTION DATA LENGTH", offsetof(MpegTSContext, dvb_audio_preselection_length), AV_OPT_TYPE_INT, 0, 0, AV_OPT_FLAG_EXPORT}, {NULL}, }; static const AVClass mpegts_class = { .class_name = "mpegts demuxer", .item_name = av_default_item_name, .option = aml_mpegts_options, .version = LIBAVUTIL_VERSION_INT, }; MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s); int avpriv_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, const uint8_t *buf, int len); void avpriv_mpegts_parse_close(MpegTSContext *ts); typedef struct SLConfigDescr { int use_au_start; int use_au_end; int use_rand_acc_pt; int use_padding; int use_timestamps; int use_idle; int timestamp_res; int timestamp_len; int ocr_len; int au_len; int inst_bitrate_len; int degr_prior_len; int au_seq_num_len; int packet_seq_num_len; } SLConfigDescr; typedef struct Mp4Descr { int es_id; int dec_config_descr_len; uint8_t *dec_config_descr; SLConfigDescr sl; } Mp4Descr; /* TS stream handling */ enum MpegTSState { MPEGTS_HEADER = 0, MPEGTS_PESHEADER, MPEGTS_PESHEADER_FILL, MPEGTS_PAYLOAD, MPEGTS_SKIP, }; /* enough for PES header + length */ #define PES_START_SIZE 6 #define PES_HEADER_SIZE 9 #define MAX_PES_HEADER_SIZE (9 + 255) typedef struct PESContext { int pid; int pcr_pid; /**< if -1 then all packets containing PCR are considered */ int stream_type; MpegTSContext *ts; AVFormatContext *stream; AVStream *st; AVStream *sub_st; /**< stream for the embedded AC3 stream in HDMV TrueHD */ enum MpegTSState state; /* used to get the format */ int data_index; int flags; /**< copied to the AVPacket flags */ int total_size; int pes_header_size; int extended_stream_id; uint8_t stream_id; int64_t pts, dts; int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ uint8_t header[MAX_PES_HEADER_SIZE]; AVBufferRef *buffer; SLConfigDescr sl; /* used to encrypt stream */ int ca_system_id;/*id for dvb ca system*/ int ecm_pid;/*ecm pid for encrypted mpegts*/ uint8_t *private_data;/*private data in ca descriptor*/ int private_data_len; } PESContext; /** * Parse an MPEG-2 descriptor * @param[in] fc Format context (used for logging only) * @param st Stream * @param stream_type STREAM_TYPE_xxx * @param pp Descriptor buffer pointer * @param desc_list_end End of buffer * @return <0 to stop processing */ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, const uint8_t **pp, const uint8_t *desc_list_end, Mp4Descr *mp4_descr, int mp4_descr_count, int pid, MpegTSContext *ts); /** * Check presence of H264 startcode * @return <0 to stop processing */ int ff_check_h264_startcode(AVFormatContext *s, const AVStream *st, const AVPacket *pkt); #endif /* AVFORMAT_MPEGTS_H */