summaryrefslogtreecommitdiff
path: root/libavformat/mpegts.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/mpegts.c')
-rw-r--r--libavformat/mpegts.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 1540a8d118..2def57371b 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -1743,17 +1743,17 @@ static int mpegts_resync(AVFormatContext *s)
}
/* return -1 if error or EOF. Return 0 if OK. */
-static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size)
+static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size, uint8_t **data)
{
AVIOContext *pb = s->pb;
- int skip, len;
+ int len;
for(;;) {
- len = avio_read(pb, buf, TS_PACKET_SIZE);
+ len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data);
if (len != TS_PACKET_SIZE)
return len < 0 ? len : AVERROR_EOF;
/* check packet sync byte */
- if (buf[0] != 0x47) {
+ if ((*data)[0] != 0x47) {
/* find a new packet start */
avio_seek(pb, -TS_PACKET_SIZE, SEEK_CUR);
if (mpegts_resync(s) < 0)
@@ -1761,19 +1761,25 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size)
else
continue;
} else {
- skip = raw_packet_size - TS_PACKET_SIZE;
- if (skip > 0)
- avio_skip(pb, skip);
break;
}
}
return 0;
}
+static void finished_reading_packet(AVFormatContext *s, int raw_packet_size)
+{
+ AVIOContext *pb = s->pb;
+ int skip = raw_packet_size - TS_PACKET_SIZE;
+ if (skip > 0)
+ avio_skip(pb, skip);
+}
+
static int handle_packets(MpegTSContext *ts, int nb_packets)
{
AVFormatContext *s = ts->stream;
uint8_t packet[TS_PACKET_SIZE+FF_INPUT_BUFFER_PADDING_SIZE];
+ uint8_t *data;
int packet_num, ret = 0;
if (avio_tell(s->pb) != ts->last_pos) {
@@ -1802,10 +1808,11 @@ static int handle_packets(MpegTSContext *ts, int nb_packets)
packet_num++;
if (nb_packets != 0 && packet_num >= nb_packets)
break;
- ret = read_packet(s, packet, ts->raw_packet_size);
+ ret = read_packet(s, packet, ts->raw_packet_size, &data);
if (ret != 0)
break;
- ret = handle_packet(ts, packet);
+ ret = handle_packet(ts, data);
+ finished_reading_packet(s, ts->raw_packet_size);
if (ret != 0)
break;
}
@@ -1909,6 +1916,7 @@ static int mpegts_read_header(AVFormatContext *s)
int64_t pcrs[2], pcr_h;
int packet_count[2];
uint8_t packet[TS_PACKET_SIZE];
+ uint8_t *data;
/* only read packets */
@@ -1924,18 +1932,21 @@ static int mpegts_read_header(AVFormatContext *s)
nb_pcrs = 0;
nb_packets = 0;
for(;;) {
- ret = read_packet(s, packet, ts->raw_packet_size);
+ ret = read_packet(s, packet, ts->raw_packet_size, &data);
if (ret < 0)
return -1;
- pid = AV_RB16(packet + 1) & 0x1fff;
+ pid = AV_RB16(data + 1) & 0x1fff;
if ((pcr_pid == -1 || pcr_pid == pid) &&
- parse_pcr(&pcr_h, &pcr_l, packet) == 0) {
+ parse_pcr(&pcr_h, &pcr_l, data) == 0) {
+ finished_reading_packet(s, ts->raw_packet_size);
pcr_pid = pid;
packet_count[nb_pcrs] = nb_packets;
pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;
nb_pcrs++;
if (nb_pcrs >= 2)
break;
+ } else {
+ finished_reading_packet(s, ts->raw_packet_size);
}
nb_packets++;
}
@@ -1967,15 +1978,19 @@ static int mpegts_raw_read_packet(AVFormatContext *s,
int64_t pcr_h, next_pcr_h, pos;
int pcr_l, next_pcr_l;
uint8_t pcr_buf[12];
+ uint8_t *data;
if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)
return AVERROR(ENOMEM);
pkt->pos= avio_tell(s->pb);
- ret = read_packet(s, pkt->data, ts->raw_packet_size);
+ ret = read_packet(s, pkt->data, ts->raw_packet_size, &data);
if (ret < 0) {
av_free_packet(pkt);
return ret;
}
+ if (data != pkt->data)
+ memcpy(pkt->data, data, ts->raw_packet_size);
+ finished_reading_packet(s, ts->raw_packet_size);
if (ts->mpeg2ts_compute_pcr) {
/* compute exact PCR for each packet */
if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) {