demux whole PES packets from TS

Originally committed as revision 18960 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Baptiste Coudurier 2009-05-27 00:44:00 +00:00
parent ed1dc74e18
commit 0c1375575a
2 changed files with 106 additions and 45 deletions

View File

@ -37,6 +37,8 @@
#define MAX_RESYNC_SIZE 4096 #define MAX_RESYNC_SIZE 4096
#define REGISTRATION_DESCRIPTOR 5 #define REGISTRATION_DESCRIPTOR 5
#define MAX_PES_PAYLOAD 200*1024
typedef struct PESContext PESContext; typedef struct PESContext PESContext;
static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type); static PESContext* add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid, int stream_type);
@ -109,6 +111,8 @@ struct MpegTSContext {
int stop_parse; int stop_parse;
/** packet containing Audio/Video data */ /** packet containing Audio/Video data */
AVPacket *pkt; AVPacket *pkt;
/** to detect seek */
int64_t last_pos;
/******************************************/ /******************************************/
/* private mpegts data */ /* private mpegts data */
@ -150,6 +154,7 @@ struct PESContext {
int64_t pts, dts; int64_t pts, dts;
int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */
uint8_t header[MAX_PES_HEADER_SIZE]; uint8_t header[MAX_PES_HEADER_SIZE];
uint8_t *buffer;
}; };
extern AVInputFormat mpegts_demuxer; extern AVInputFormat mpegts_demuxer;
@ -336,6 +341,8 @@ static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter)
if (filter->type == MPEGTS_SECTION) if (filter->type == MPEGTS_SECTION)
av_freep(&filter->u.section_filter.section_buf); av_freep(&filter->u.section_filter.section_buf);
else if (filter->type == MPEGTS_PES) { else if (filter->type == MPEGTS_PES) {
PESContext *pes = filter->u.pes_filter.opaque;
av_freep(&pes->buffer);
/* referenced private data will be freed later in /* referenced private data will be freed later in
* av_close_input_stream */ * av_close_input_stream */
if (!((PESContext *)filter->u.pes_filter.opaque)->st) { if (!((PESContext *)filter->u.pes_filter.opaque)->st) {
@ -797,6 +804,28 @@ static int64_t get_pts(const uint8_t *p)
return pts; return pts;
} }
static void new_pes_packet(PESContext *pes, AVPacket *pkt)
{
av_init_packet(pkt);
pkt->destruct = av_destruct_packet;
pkt->data = pes->buffer;
pkt->size = pes->data_index;
memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
pkt->stream_index = pes->st->index;
pkt->pts = pes->pts;
pkt->dts = pes->dts;
/* store position of first TS packet of this PES packet */
pkt->pos = pes->ts_packet_pos;
/* reset pts values */
pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE;
pes->buffer = NULL;
pes->data_index = 0;
}
/* return non zero if a packet could be constructed */ /* return non zero if a packet could be constructed */
static void mpegts_push_data(MpegTSFilter *filter, static void mpegts_push_data(MpegTSFilter *filter,
const uint8_t *buf, int buf_size, int is_start, const uint8_t *buf, int buf_size, int is_start,
@ -811,6 +840,10 @@ static void mpegts_push_data(MpegTSFilter *filter,
return; return;
if (is_start) { if (is_start) {
if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) {
new_pes_packet(pes, ts->pkt);
ts->stop_parse = 1;
}
pes->state = MPEGTS_HEADER; pes->state = MPEGTS_HEADER;
pes->data_index = 0; pes->data_index = 0;
pes->ts_packet_pos = pos; pes->ts_packet_pos = pos;
@ -845,8 +878,6 @@ static void mpegts_push_data(MpegTSFilter *filter,
pes->total_size = AV_RB16(pes->header + 4); pes->total_size = AV_RB16(pes->header + 4);
/* NOTE: a zero total size means the PES size is /* NOTE: a zero total size means the PES size is
unbounded */ unbounded */
if (pes->total_size)
pes->total_size += 6;
pes->pes_header_size = pes->header[8] + 9; pes->pes_header_size = pes->header[8] + 9;
} else { } else {
/* otherwise, it should be a table */ /* otherwise, it should be a table */
@ -884,33 +915,33 @@ static void mpegts_push_data(MpegTSFilter *filter,
pes->dts = get_pts(r); pes->dts = get_pts(r);
r += 5; r += 5;
} }
if (pes->total_size > pes->data_index - 6)
pes->total_size -= pes->data_index - 6;
else
pes->total_size = MAX_PES_PAYLOAD;
/* allocate pes buffer */
pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE);
if (!pes->buffer)
return;
/* we got the full header. We parse it and get the payload */ /* we got the full header. We parse it and get the payload */
pes->state = MPEGTS_PAYLOAD; pes->state = MPEGTS_PAYLOAD;
pes->data_index = 0;
} }
break; break;
case MPEGTS_PAYLOAD: case MPEGTS_PAYLOAD:
if (pes->total_size) { if (buf_size > 0) {
len = pes->total_size - pes->data_index; if (pes->data_index+buf_size > pes->total_size) {
if (len > buf_size) new_pes_packet(pes, ts->pkt);
len = buf_size; pes->total_size = MAX_PES_PAYLOAD;
} else { pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE);
len = buf_size; if (!pes->buffer)
} return;
if (len > 0) {
AVPacket *pkt = ts->pkt;
if (pes->st && av_new_packet(pkt, len) == 0) {
memcpy(pkt->data, p, len);
pkt->stream_index = pes->st->index;
pkt->pts = pes->pts;
pkt->dts = pes->dts;
/* store position of first TS packet of this PES packet */
pkt->pos = pes->ts_packet_pos;
/* reset pts values */
pes->pts = AV_NOPTS_VALUE;
pes->dts = AV_NOPTS_VALUE;
ts->stop_parse = 1; ts->stop_parse = 1;
return;
} }
memcpy(pes->buffer+pes->data_index, p, buf_size);
pes->data_index += buf_size;
} }
buf_size = 0; buf_size = 0;
break; break;
@ -1376,9 +1407,39 @@ static int mpegts_read_packet(AVFormatContext *s,
AVPacket *pkt) AVPacket *pkt)
{ {
MpegTSContext *ts = s->priv_data; MpegTSContext *ts = s->priv_data;
int ret, i;
if (url_ftell(s->pb) != ts->last_pos) {
/* seek detected, flush pes buffer */
for (i = 0; i < NB_PID_MAX; i++) {
if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
av_freep(&pes->buffer);
pes->data_index = 0;
pes->state = MPEGTS_SKIP; /* skip until pes header */
}
}
}
ts->pkt = pkt; ts->pkt = pkt;
return handle_packets(ts, 0); ret = handle_packets(ts, 0);
if (ret < 0) {
/* flush pes data left */
for (i = 0; i < NB_PID_MAX; i++) {
if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
PESContext *pes = ts->pids[i]->u.pes_filter.opaque;
if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) {
new_pes_packet(pes, pkt);
ret = 0;
break;
}
}
}
}
ts->last_pos = url_ftell(s->pb);
return ret;
} }
static int mpegts_read_close(AVFormatContext *s) static int mpegts_read_close(AVFormatContext *s)

View File

@ -3599,57 +3599,57 @@ ret:-1 st:-1 ts:-0.645825 flags:1
tests/data/b-lavf.ts tests/data/b-lavf.ts
ret: 0 st: 0 dts:0.660000 pts:0.700000 pos:564 size:24921 flags:1 ret: 0 st: 0 dts:0.660000 pts:0.700000 pos:564 size:24921 flags:1
ret: 0 st:-1 ts:-1.000000 flags:0 ret: 0 st:-1 ts:-1.000000 flags:0
ret: 0 st: 0 dts:0.043533 pts:-102481911520608.625000 pos:29328 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st:-1 ts:1.894167 flags:1 ret: 0 st:-1 ts:1.894167 flags:1
ret: 0 st: 0 dts:0.780000 pts:0.820000 pos:65800 size:14260 flags:0 ret: 0 st: 0 dts:0.780000 pts:0.820000 pos:65800 size:14260 flags:0
ret: 0 st: 0 ts:0.788333 flags:0 ret: 0 st: 0 ts:0.788333 flags:0
ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st: 0 ts:-0.317500 flags:1 ret: 0 st: 0 ts:-0.317500 flags:1
ret: 0 st: 0 dts:0.027333 pts:-102481911520608.625000 pos:48504 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st: 1 ts:2.576667 flags:0 ret: 0 st: 1 ts:2.576667 flags:0
ret: 0 st: 0 dts:2.581533 pts:-102481911520608.625000 pos:29328 size:6340 flags:1 ret: 0 st: 0 dts:0.860000 pts:0.900000 pos:98512 size:12495 flags:0
ret: 0 st: 1 ts:1.470833 flags:1 ret: 0 st: 1 ts:1.470833 flags:1
ret: 0 st: 0 dts:1.458333 pts:-102481911520608.625000 pos:98512 size:10644 flags:1 ret: 0 st: 0 dts:0.780000 pts:0.820000 pos:65800 size:14260 flags:0
ret: 0 st:-1 ts:0.365002 flags:0 ret: 0 st:-1 ts:0.365002 flags:0
ret: 0 st: 0 dts:0.367533 pts:-102481911520608.625000 pos:65800 size:12060 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st:-1 ts:-0.740831 flags:1 ret: 0 st:-1 ts:-0.740831 flags:1
ret: 0 st: 0 dts:0.027333 pts:-102481911520608.625000 pos:29328 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st: 0 ts:2.153333 flags:0 ret: 0 st: 0 ts:2.153333 flags:0
ret: 0 st: 0 dts:2.160333 pts:-102481911520608.625000 pos:29328 size:5391 flags:1 ret: 0 st: 0 dts:0.820000 pts:0.860000 pos:82344 size:13937 flags:0
ret: 0 st: 0 ts:1.047500 flags:1 ret: 0 st: 0 ts:1.047500 flags:1
ret: 0 st: 0 dts:1.037133 pts:-102481911520608.625000 pos:82344 size:8888 flags:1 ret: 0 st: 0 dts:0.740000 pts:0.780000 pos:48504 size:14617 flags:0
ret: 0 st: 1 ts:-0.058333 flags:0 ret: 0 st: 1 ts:-0.058333 flags:0
ret: 0 st: 0 dts:0.043533 pts:-102481911520608.625000 pos:48504 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st: 1 ts:2.835833 flags:1 ret: 0 st: 1 ts:2.835833 flags:1
ret: 0 st: 0 dts:0.860000 pts:0.900000 pos:98512 size:12495 flags:0 ret: 0 st: 0 dts:0.860000 pts:0.900000 pos:98512 size:12495 flags:0
ret: 0 st:-1 ts:1.730004 flags:0 ret: 0 st:-1 ts:1.730004 flags:0
ret: 0 st: 0 dts:1.755333 pts:-102481911520608.625000 pos:113176 size:852 flags:1 ret: 0 st: 0 dts:0.780000 pts:0.820000 pos:65800 size:14260 flags:0
ret: 0 st:-1 ts:0.624171 flags:1 ret: 0 st:-1 ts:0.624171 flags:1
ret: 0 st: 0 dts:0.621333 pts:-102481911520608.625000 pos:65800 size:5532 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st: 0 ts:-0.481667 flags:0 ret: 0 st: 0 ts:-0.481667 flags:0
ret: 0 st: 0 dts:0.043533 pts:-102481911520608.625000 pos:29328 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st: 0 ts:2.412500 flags:1 ret: 0 st: 0 ts:2.412500 flags:1
ret: 0 st: 0 dts:2.408733 pts:-102481911520608.625000 pos:29328 size:9604 flags:1 ret: 0 st: 0 dts:0.860000 pts:0.900000 pos:98512 size:12495 flags:0
ret: 0 st: 1 ts:1.306667 flags:0 ret: 0 st: 1 ts:1.306667 flags:0
ret: 0 st: 0 dts:0.740000 pts:0.780000 pos:48504 size:14617 flags:0 ret: 0 st: 0 dts:0.740000 pts:0.780000 pos:48504 size:14617 flags:0
ret: 0 st: 1 ts:0.200844 flags:1 ret: 0 st: 1 ts:0.200844 flags:1
ret: 0 st: 0 dts:0.200133 pts:-102481911520608.625000 pos:65800 size:18588 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st:-1 ts:-0.904994 flags:0 ret: 0 st:-1 ts:-0.904994 flags:0
ret: 0 st: 0 dts:0.043533 pts:-102481911520608.625000 pos:29328 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st:-1 ts:1.989173 flags:1 ret: 0 st:-1 ts:1.989173 flags:1
ret: 0 st: 0 dts:1.987533 pts:-102481911520608.625000 pos:29328 size:8655 flags:1 ret: 0 st: 0 dts:0.820000 pts:0.860000 pos:82344 size:13937 flags:0
ret: 0 st: 0 ts:0.883344 flags:0 ret: 0 st: 0 ts:0.883344 flags:0
ret: 0 st: 0 dts:0.896733 pts:-102481911520608.625000 pos:82344 size:12152 flags:1 ret: 0 st: 0 dts:0.740000 pts:0.780000 pos:48504 size:14617 flags:0
ret: 0 st: 0 ts:-0.222489 flags:1 ret: 0 st: 0 ts:-0.222489 flags:1
ret: 0 st: 0 dts:0.027333 pts:-102481911520608.625000 pos:48504 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st: 1 ts:2.671678 flags:0 ret: 0 st: 1 ts:2.671678 flags:0
ret: 0 st: 0 dts:2.673333 pts:-102481911520608.625000 pos:29328 size:3076 flags:1 ret: 0 st: 0 dts:0.860000 pts:0.900000 pos:98512 size:12495 flags:0
ret: 0 st: 1 ts:1.565844 flags:1 ret: 0 st: 1 ts:1.565844 flags:1
ret: 0 st: 0 dts:1.550133 pts:-102481911520608.625000 pos:98512 size:7380 flags:1 ret: 0 st: 0 dts:0.780000 pts:0.820000 pos:65800 size:14260 flags:0
ret: 0 st:-1 ts:0.460008 flags:0 ret: 0 st:-1 ts:0.460008 flags:0
ret: 0 st: 0 dts:0.475533 pts:-102481911520608.625000 pos:65800 size:8796 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
ret: 0 st:-1 ts:-0.645825 flags:1 ret: 0 st:-1 ts:-0.645825 flags:1
ret: 0 st: 0 dts:0.027333 pts:-102481911520608.625000 pos:29328 size:21852 flags:1 ret: 0 st: 0 dts:0.700000 pts:0.740000 pos:29328 size:16309 flags:0
---------------- ----------------
tests/data/b-lavf.ul tests/data/b-lavf.ul
ret: 0 st: 0 dts:0.000000 pts:0.000000 pos:0 size:1024 flags:1 ret: 0 st: 0 dts:0.000000 pts:0.000000 pos:0 size:1024 flags:1