327 lines
10 KiB
C
327 lines
10 KiB
C
/*
|
|
* 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 */
|