mirror of https://git.ffmpeg.org/ffmpeg.git
avformat/mpegts: reduce buffering during initialization
Reduces buffering latency with low bitrate streams, where 8192 bytes can mean several seconds. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
147ef1d947
commit
0a84ba2608
|
@ -56,6 +56,9 @@
|
||||||
(prev_dividend) = (dividend); \
|
(prev_dividend) = (dividend); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define PROBE_PACKET_MAX_BUF 8192
|
||||||
|
#define PROBE_PACKET_MARGIN 5
|
||||||
|
|
||||||
enum MpegTSFilterType {
|
enum MpegTSFilterType {
|
||||||
MPEGTS_PES,
|
MPEGTS_PES,
|
||||||
MPEGTS_SECTION,
|
MPEGTS_SECTION,
|
||||||
|
@ -594,28 +597,42 @@ static int analyze(const uint8_t *buf, int size, int packet_size,
|
||||||
return best_score - FFMAX(stat_all - 10*best_score, 0)/10;
|
return best_score - FFMAX(stat_all - 10*best_score, 0)/10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* autodetect fec presence. Must have at least 1024 bytes */
|
/* autodetect fec presence */
|
||||||
static int get_packet_size(const uint8_t *buf, int size)
|
static int get_packet_size(AVFormatContext* s)
|
||||||
{
|
{
|
||||||
int score, fec_score, dvhs_score;
|
int score, fec_score, dvhs_score;
|
||||||
|
int margin;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (size < (TS_FEC_PACKET_SIZE * 5 + 1))
|
/*init buffer to store stream for probing */
|
||||||
return AVERROR_INVALIDDATA;
|
uint8_t buf[PROBE_PACKET_MAX_BUF] = {0};
|
||||||
|
int buf_size = 0;
|
||||||
|
|
||||||
score = analyze(buf, size, TS_PACKET_SIZE, 0);
|
while (buf_size < PROBE_PACKET_MAX_BUF) {
|
||||||
dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, 0);
|
ret = avio_read_partial(s->pb, buf + buf_size, PROBE_PACKET_MAX_BUF - buf_size);
|
||||||
fec_score = analyze(buf, size, TS_FEC_PACKET_SIZE, 0);
|
if (ret < 0)
|
||||||
av_log(NULL, AV_LOG_TRACE, "score: %d, dvhs_score: %d, fec_score: %d \n",
|
return AVERROR_INVALIDDATA;
|
||||||
score, dvhs_score, fec_score);
|
buf_size += ret;
|
||||||
|
|
||||||
if (score > fec_score && score > dvhs_score)
|
score = analyze(buf, buf_size, TS_PACKET_SIZE, 0);
|
||||||
return TS_PACKET_SIZE;
|
dvhs_score = analyze(buf, buf_size, TS_DVHS_PACKET_SIZE, 0);
|
||||||
else if (dvhs_score > score && dvhs_score > fec_score)
|
fec_score = analyze(buf, buf_size, TS_FEC_PACKET_SIZE, 0);
|
||||||
return TS_DVHS_PACKET_SIZE;
|
av_log(s, AV_LOG_TRACE, "Probe: %d, score: %d, dvhs_score: %d, fec_score: %d \n",
|
||||||
else if (score < fec_score && dvhs_score < fec_score)
|
buf_size, score, dvhs_score, fec_score);
|
||||||
return TS_FEC_PACKET_SIZE;
|
|
||||||
else
|
if (buf_size < PROBE_PACKET_MAX_BUF)
|
||||||
return AVERROR_INVALIDDATA;
|
margin = PROBE_PACKET_MARGIN; /*if buffer not filled */
|
||||||
|
else
|
||||||
|
margin = 0;
|
||||||
|
|
||||||
|
if (score > FFMAX(fec_score, dvhs_score) + margin)
|
||||||
|
return TS_PACKET_SIZE;
|
||||||
|
else if (dvhs_score > FFMAX(score, fec_score) + margin)
|
||||||
|
return TS_DVHS_PACKET_SIZE;
|
||||||
|
else if (fec_score > FFMAX(score, dvhs_score) + margin)
|
||||||
|
return TS_FEC_PACKET_SIZE;
|
||||||
|
}
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct SectionHeader {
|
typedef struct SectionHeader {
|
||||||
|
@ -2933,8 +2950,6 @@ static int mpegts_read_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
MpegTSContext *ts = s->priv_data;
|
MpegTSContext *ts = s->priv_data;
|
||||||
AVIOContext *pb = s->pb;
|
AVIOContext *pb = s->pb;
|
||||||
uint8_t buf[8 * 1024] = {0};
|
|
||||||
int len;
|
|
||||||
int64_t pos, probesize = s->probesize;
|
int64_t pos, probesize = s->probesize;
|
||||||
|
|
||||||
s->internal->prefer_codec_framerate = 1;
|
s->internal->prefer_codec_framerate = 1;
|
||||||
|
@ -2942,10 +2957,8 @@ static int mpegts_read_header(AVFormatContext *s)
|
||||||
if (ffio_ensure_seekback(pb, probesize) < 0)
|
if (ffio_ensure_seekback(pb, probesize) < 0)
|
||||||
av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");
|
av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");
|
||||||
|
|
||||||
/* read the first 8192 bytes to get packet size */
|
|
||||||
pos = avio_tell(pb);
|
pos = avio_tell(pb);
|
||||||
len = avio_read(pb, buf, sizeof(buf));
|
ts->raw_packet_size = get_packet_size(s);
|
||||||
ts->raw_packet_size = get_packet_size(buf, len);
|
|
||||||
if (ts->raw_packet_size <= 0) {
|
if (ts->raw_packet_size <= 0) {
|
||||||
av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n");
|
av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n");
|
||||||
ts->raw_packet_size = TS_PACKET_SIZE;
|
ts->raw_packet_size = TS_PACKET_SIZE;
|
||||||
|
|
Loading…
Reference in New Issue