X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmpegts.c;h=8a84e5cc1903dda1877e4a28bc84e656a3257e2e;hb=76ef18fd3910a5b479a3d9e584a0adc13f0d84ee;hp=e7bbf3e488980c27c392802b1b49014621535e69;hpb=f05f210526a3dc2d9fa6b1c228e3907ebd1d43c6;p=ffmpeg diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index e7bbf3e4889..8a84e5cc190 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -56,6 +56,9 @@ (prev_dividend) = (dividend); \ } while (0) +#define PROBE_PACKET_MAX_BUF 8192 +#define PROBE_PACKET_MARGIN 5 + enum MpegTSFilterType { MPEGTS_PES, 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; } -/* autodetect fec presence. Must have at least 1024 bytes */ -static int get_packet_size(const uint8_t *buf, int size) +/* autodetect fec presence */ +static int get_packet_size(AVFormatContext* s) { int score, fec_score, dvhs_score; + int margin; + int ret; - if (size < (TS_FEC_PACKET_SIZE * 5 + 1)) - return AVERROR_INVALIDDATA; + /*init buffer to store stream for probing */ + uint8_t buf[PROBE_PACKET_MAX_BUF] = {0}; + int buf_size = 0; - score = analyze(buf, size, TS_PACKET_SIZE, 0); - dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, 0); - fec_score = analyze(buf, size, TS_FEC_PACKET_SIZE, 0); - av_log(NULL, AV_LOG_TRACE, "score: %d, dvhs_score: %d, fec_score: %d \n", - score, dvhs_score, fec_score); - - if (score > fec_score && score > dvhs_score) - return TS_PACKET_SIZE; - else if (dvhs_score > score && dvhs_score > fec_score) - return TS_DVHS_PACKET_SIZE; - else if (score < fec_score && dvhs_score < fec_score) - return TS_FEC_PACKET_SIZE; - else - return AVERROR_INVALIDDATA; + while (buf_size < PROBE_PACKET_MAX_BUF) { + ret = avio_read_partial(s->pb, buf + buf_size, PROBE_PACKET_MAX_BUF - buf_size); + if (ret < 0) + return AVERROR_INVALIDDATA; + buf_size += ret; + + score = analyze(buf, buf_size, TS_PACKET_SIZE, 0); + dvhs_score = analyze(buf, buf_size, TS_DVHS_PACKET_SIZE, 0); + fec_score = analyze(buf, buf_size, TS_FEC_PACKET_SIZE, 0); + av_log(s, AV_LOG_TRACE, "Probe: %d, score: %d, dvhs_score: %d, fec_score: %d \n", + buf_size, score, dvhs_score, fec_score); + + margin = mid_pred(score, fec_score, dvhs_score); + + if (buf_size < PROBE_PACKET_MAX_BUF) + margin += PROBE_PACKET_MARGIN; /*if buffer not filled */ + + if (score > margin) + return TS_PACKET_SIZE; + else if (dvhs_score > margin) + return TS_DVHS_PACKET_SIZE; + else if (fec_score > margin) + return TS_FEC_PACKET_SIZE; + } + return AVERROR_INVALIDDATA; } typedef struct SectionHeader { @@ -2851,7 +2868,7 @@ static int handle_packets(MpegTSContext *ts, int64_t nb_packets) return ret; } -static int mpegts_probe(AVProbeData *p) +static int mpegts_probe(const AVProbeData *p) { const int size = p->buf_size; int maxscore = 0; @@ -2933,8 +2950,6 @@ static int mpegts_read_header(AVFormatContext *s) { MpegTSContext *ts = s->priv_data; AVIOContext *pb = s->pb; - uint8_t buf[8 * 1024] = {0}; - int len; int64_t pos, probesize = s->probesize; s->internal->prefer_codec_framerate = 1; @@ -2942,10 +2957,8 @@ static int mpegts_read_header(AVFormatContext *s) if (ffio_ensure_seekback(pb, probesize) < 0) 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); - len = avio_read(pb, buf, sizeof(buf)); - ts->raw_packet_size = get_packet_size(buf, len); + ts->raw_packet_size = get_packet_size(s); if (ts->raw_packet_size <= 0) { 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;