From 2fbdfba0f2d1851f894002d9d5930799629cc194 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 6 Jun 2014 05:06:12 +0200 Subject: [PATCH] avformat/flvdec: Support live flv / NGINX RTMP streams Fixes Ticket3553 Signed-off-by: Michael Niedermayer --- libavformat/allformats.c | 1 + libavformat/flvdec.c | 45 +++++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 30e5d30d36..dc5557c091 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -123,6 +123,7 @@ void av_register_all(void) REGISTER_MUXDEMUX(FLAC, flac); REGISTER_DEMUXER (FLIC, flic); REGISTER_MUXDEMUX(FLV, flv); + REGISTER_DEMUXER (LIVE_FLV, live_flv); REGISTER_DEMUXER (FOURXM, fourxm); REGISTER_MUXER (FRAMECRC, framecrc); REGISTER_MUXER (FRAMEMD5, framemd5); diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index e113cc3f6c..cc40a53ba8 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -56,21 +56,35 @@ typedef struct { int searched_for_end; } FLVContext; -static int flv_probe(AVProbeData *p) +static int probe(AVProbeData *p, int live) { - const uint8_t *d; + const uint8_t *d = p->buf; + unsigned offset = AV_RB32(d + 5); - d = p->buf; if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5] == 0 && - AV_RB32(d + 5) > 8) { - return AVPROBE_SCORE_MAX; + offset + 100 < p->buf_size && + offset > 8) { + int is_live = !memcmp(d + offset + 40, "NGINX RTMP", 10); + + if (live == is_live) + return AVPROBE_SCORE_MAX; } return 0; } +static int flv_probe(AVProbeData *p) +{ + return probe(p, 0); +} + +static int live_flv_probe(AVProbeData *p) +{ + return probe(p, 1); +} + static AVStream *create_stream(AVFormatContext *s, int codec_type) { AVStream *st = avformat_new_stream(s, NULL); @@ -1049,3 +1063,24 @@ AVInputFormat ff_flv_demuxer = { .extensions = "flv", .priv_class = &flv_class, }; + +static const AVClass live_flv_class = { + .class_name = "flvdec", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVInputFormat ff_live_flv_demuxer = { + .name = "live_flv", + .long_name = NULL_IF_CONFIG_SMALL("live RTMP FLV (Flash Video)"), + .priv_data_size = sizeof(FLVContext), + .read_probe = live_flv_probe, + .read_header = flv_read_header, + .read_packet = flv_read_packet, + .read_seek = flv_read_seek, + .read_close = flv_read_close, + .extensions = "flv", + .priv_class = &live_flv_class, + .flags = AVFMT_TS_DISCONT +};