mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2025-02-21 13:22:13 +00:00
Merge remote-tracking branch 'cus/stable'
* cus/stable: mpegts: fix teletext pts of streams with standalone pcr pid mpegts: add pcr filter for tracking standalone pcr pids mpegts: factorize mpegts filter creator code mpegts: move last_pcr to MpegTSFilter level Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
2765c2ec7d
@ -55,12 +55,13 @@
|
||||
enum MpegTSFilterType {
|
||||
MPEGTS_PES,
|
||||
MPEGTS_SECTION,
|
||||
MPEGTS_PCR,
|
||||
};
|
||||
|
||||
typedef struct MpegTSFilter MpegTSFilter;
|
||||
|
||||
typedef int PESCallback (MpegTSFilter *f, const uint8_t *buf, int len,
|
||||
int is_start, int64_t pos, int64_t cur_pcr);
|
||||
int is_start, int64_t pos);
|
||||
|
||||
typedef struct MpegTSPESFilter {
|
||||
PESCallback *pes_cb;
|
||||
@ -85,6 +86,7 @@ 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;
|
||||
@ -216,7 +218,6 @@ typedef struct PESContext {
|
||||
uint8_t header[MAX_PES_HEADER_SIZE];
|
||||
AVBufferRef *buffer;
|
||||
SLConfigDescr sl;
|
||||
int64_t last_pcr;
|
||||
} PESContext;
|
||||
|
||||
extern AVInputFormat ff_mpegts_demuxer;
|
||||
@ -405,14 +406,10 @@ static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
|
||||
}
|
||||
}
|
||||
|
||||
static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts,
|
||||
unsigned int pid,
|
||||
SectionCallback *section_cb,
|
||||
void *opaque,
|
||||
int check_crc)
|
||||
static MpegTSFilter *mpegts_open_filter(MpegTSContext *ts, unsigned int pid,
|
||||
enum MpegTSFilterType type)
|
||||
{
|
||||
MpegTSFilter *filter;
|
||||
MpegTSSectionFilter *sec;
|
||||
|
||||
av_dlog(ts->stream, "Filter: pid=0x%x\n", pid);
|
||||
|
||||
@ -423,11 +420,26 @@ static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts,
|
||||
return NULL;
|
||||
ts->pids[pid] = filter;
|
||||
|
||||
filter->type = MPEGTS_SECTION;
|
||||
filter->type = type;
|
||||
filter->pid = pid;
|
||||
filter->es_id = -1;
|
||||
filter->last_cc = -1;
|
||||
filter->last_pcr= -1;
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts,
|
||||
unsigned int pid,
|
||||
SectionCallback *section_cb,
|
||||
void *opaque,
|
||||
int check_crc)
|
||||
{
|
||||
MpegTSFilter *filter;
|
||||
MpegTSSectionFilter *sec;
|
||||
|
||||
if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_SECTION)))
|
||||
return NULL;
|
||||
sec = &filter->u.section_filter;
|
||||
sec->section_cb = section_cb;
|
||||
sec->opaque = opaque;
|
||||
@ -447,17 +459,8 @@ static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid,
|
||||
MpegTSFilter *filter;
|
||||
MpegTSPESFilter *pes;
|
||||
|
||||
if (pid >= NB_PID_MAX || ts->pids[pid])
|
||||
if (!(filter = mpegts_open_filter(ts, pid, MPEGTS_PES)))
|
||||
return NULL;
|
||||
filter = av_mallocz(sizeof(MpegTSFilter));
|
||||
if (!filter)
|
||||
return NULL;
|
||||
|
||||
ts->pids[pid] = filter;
|
||||
filter->type = MPEGTS_PES;
|
||||
filter->pid = pid;
|
||||
filter->es_id = -1;
|
||||
filter->last_cc = -1;
|
||||
|
||||
pes = &filter->u.pes_filter;
|
||||
pes->pes_cb = pes_cb;
|
||||
@ -465,6 +468,11 @@ static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid,
|
||||
return filter;
|
||||
}
|
||||
|
||||
static MpegTSFilter *mpegts_open_pcr_filter(MpegTSContext *ts, unsigned int pid)
|
||||
{
|
||||
return mpegts_open_filter(ts, pid, MPEGTS_PCR);
|
||||
}
|
||||
|
||||
static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
|
||||
{
|
||||
int pid;
|
||||
@ -891,7 +899,7 @@ static int read_sl_header(PESContext *pes, SLConfigDescr *sl,
|
||||
/* return non zero if a packet could be constructed */
|
||||
static int mpegts_push_data(MpegTSFilter *filter,
|
||||
const uint8_t *buf, int buf_size, int is_start,
|
||||
int64_t pos, int64_t pcr)
|
||||
int64_t pos)
|
||||
{
|
||||
PESContext *pes = filter->u.pes_filter.opaque;
|
||||
MpegTSContext *ts = pes->ts;
|
||||
@ -901,9 +909,6 @@ static int mpegts_push_data(MpegTSFilter *filter,
|
||||
if (!ts->pkt)
|
||||
return 0;
|
||||
|
||||
if (pcr != -1)
|
||||
pes->last_pcr = pcr;
|
||||
|
||||
if (is_start) {
|
||||
if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) {
|
||||
new_pes_packet(pes, ts->pkt);
|
||||
@ -1066,16 +1071,28 @@ skip:
|
||||
while ((p = av_find_program_from_stream(pes->stream, p, pes->st->index))) {
|
||||
if (p->pcr_pid != -1 && p->discard != AVDISCARD_ALL) {
|
||||
MpegTSFilter *f = pes->ts->pids[p->pcr_pid];
|
||||
if (f && f->type == MPEGTS_PES) {
|
||||
PESContext *pcrpes = f->u.pes_filter.opaque;
|
||||
if (pcrpes && pcrpes->last_pcr != -1 && pcrpes->st && pcrpes->st->discard != AVDISCARD_ALL) {
|
||||
if (f) {
|
||||
AVStream *st = NULL;
|
||||
if (f->type == MPEGTS_PES) {
|
||||
PESContext *pcrpes = f->u.pes_filter.opaque;
|
||||
if (pcrpes)
|
||||
st = pcrpes->st;
|
||||
} else if (f->type == MPEGTS_PCR) {
|
||||
int i;
|
||||
for (i = 0; i < p->nb_stream_indexes; i++) {
|
||||
AVStream *pst = pes->stream->streams[p->stream_index[i]];
|
||||
if (pst->codec->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
st = pst;
|
||||
}
|
||||
}
|
||||
if (f->last_pcr != -1 && st && st->discard != AVDISCARD_ALL) {
|
||||
// teletext packets do not always have correct timestamps,
|
||||
// the standard says they should be handled after 40.6 ms at most,
|
||||
// and the pcr error to this packet should be no more than 100 ms.
|
||||
// TODO: we should interpolate the PCR, not just use the last one
|
||||
int64_t pcr = pcrpes->last_pcr / 300;
|
||||
pes->st->pts_wrap_reference = pcrpes->st->pts_wrap_reference;
|
||||
pes->st->pts_wrap_behavior = pcrpes->st->pts_wrap_behavior;
|
||||
int64_t pcr = f->last_pcr / 300;
|
||||
pes->st->pts_wrap_reference = st->pts_wrap_reference;
|
||||
pes->st->pts_wrap_behavior = st->pts_wrap_behavior;
|
||||
if (pes->dts == AV_NOPTS_VALUE || pes->dts < pcr) {
|
||||
pes->pts = pes->dts = pcr;
|
||||
} else if (pes->dts > pcr + 3654 + 9000) {
|
||||
@ -1146,7 +1163,6 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid)
|
||||
pes->state = MPEGTS_SKIP;
|
||||
pes->pts = AV_NOPTS_VALUE;
|
||||
pes->dts = AV_NOPTS_VALUE;
|
||||
pes->last_pcr= -1;
|
||||
tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes);
|
||||
if (!tss) {
|
||||
av_free(pes);
|
||||
@ -1826,6 +1842,9 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
|
||||
p = desc_list_end;
|
||||
}
|
||||
|
||||
if (!ts->pids[pcr_pid])
|
||||
mpegts_open_pcr_filter(ts, pcr_pid);
|
||||
|
||||
out:
|
||||
for (i = 0; i < mp4_descr_count; i++)
|
||||
av_free(mp4_descr[i].dec_config_descr);
|
||||
@ -2031,7 +2050,7 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_payload)
|
||||
if (!has_payload && tss->type != MPEGTS_PCR)
|
||||
return 0;
|
||||
p = packet + 4;
|
||||
if (has_adaptation) {
|
||||
@ -2040,7 +2059,7 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
|
||||
}
|
||||
/* if past the end of packet, ignore */
|
||||
p_end = packet + TS_PACKET_SIZE;
|
||||
if (p >= p_end)
|
||||
if (p > p_end || (p == p_end && tss->type != MPEGTS_PCR))
|
||||
return 0;
|
||||
|
||||
pos = avio_tell(ts->stream->pb);
|
||||
@ -2093,15 +2112,16 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet)
|
||||
|
||||
} else {
|
||||
int ret;
|
||||
int64_t pcr = -1;
|
||||
int64_t pcr_h;
|
||||
int pcr_l;
|
||||
if (parse_pcr(&pcr_h, &pcr_l, packet) == 0)
|
||||
pcr = pcr_h * 300 + pcr_l;
|
||||
tss->last_pcr = pcr_h * 300 + pcr_l;
|
||||
// Note: The position here points actually behind the current packet.
|
||||
if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
|
||||
pos - ts->raw_packet_size, pcr)) < 0)
|
||||
return ret;
|
||||
if (tss->type == MPEGTS_PES) {
|
||||
if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
|
||||
pos - ts->raw_packet_size)) < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2217,9 +2237,9 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
|
||||
av_buffer_unref(&pes->buffer);
|
||||
pes->data_index = 0;
|
||||
pes->state = MPEGTS_SKIP; /* skip until pes header */
|
||||
pes->last_pcr = -1;
|
||||
}
|
||||
ts->pids[i]->last_cc = -1;
|
||||
ts->pids[i]->last_pcr = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user