mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-20 06:11:04 +00:00
mpegts: Remove one memcpy per packet
This was being performed to ensure that a complete packet was held in contiguous memory, prior to parsing the packet. However, the source buffer is typically large enough that the packet was already contiguous, so it is beneficial to return the packet by reference in most cases. Before After Mean StdDev Mean StdDev Change memcpy 720.7 32.7 649.8 25.1 +10.9% Overall 2372.7 46.1 2291.7 21.8 +3.5% Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
daf1e0d3de
commit
cabb168169
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user