From 96aaffd8a0abd4d010adc46ea1748c23846e06d8 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 22 Apr 2013 16:40:43 +0200 Subject: libav decoder plugin: do not explicitly probe the input format in libav_decode() avformat_open_input() can probe the format itself. --- src/decoder/libav_decoder_plugin.c | 97 ++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/src/decoder/libav_decoder_plugin.c b/src/decoder/libav_decoder_plugin.c index 026f0c9c..fd404e29 100644 --- a/src/decoder/libav_decoder_plugin.c +++ b/src/decoder/libav_decoder_plugin.c @@ -50,7 +50,6 @@ typedef struct LibavDecContext { struct input_stream *input; AVIOContext *io; - unsigned char buffer[8192]; } LibavDecContext; static GLogLevelFlags @@ -107,14 +106,22 @@ mpd_libav_stream_seek(void *opaque, int64_t pos, int whence) return stream->input->offset; } +#define INPUT_BUFFER_SIZE 16384 static int mpd_libav_stream_open(LibavDecContext *s, struct input_stream *input) { + uint8_t *buf = av_malloc(INPUT_BUFFER_SIZE); + + if (!buf) + return AVERROR(ENOMEM); + s->input = input; - s->io = avio_alloc_context(s->buffer, sizeof(s->buffer), 0, + s->io = avio_alloc_context(buf, INPUT_BUFFER_SIZE, 0, s, mpd_libav_stream_read, NULL, input->seekable ? mpd_libav_stream_seek : NULL); - if (!s->io) + if (!s->io) { + av_freep(&buf); return AVERROR(ENOMEM); + } return 0; } @@ -141,6 +148,7 @@ mpd_libav_open_input(AVFormatContext **ic_ptr, static void mpd_libav_stream_close(LibavDecContext *stream) { + av_freep(&stream->io->buffer); av_free(stream->io); } @@ -288,53 +296,11 @@ libav_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context) } } -static AVInputFormat * -libav_probe(struct decoder *decoder, struct input_stream *is) -{ - enum { - BUFFER_SIZE = 16384, - PADDING = 16, - }; - - unsigned char *buffer = g_malloc(BUFFER_SIZE); - size_t nbytes = decoder_read(decoder, is, buffer, BUFFER_SIZE); - if (nbytes <= PADDING || - !input_stream_lock_seek(is, 0, SEEK_SET, NULL)) { - g_free(buffer); - return NULL; - } - - /* some ffmpeg parsers (e.g. ac3_parser.c) read a few bytes - beyond the declared buffer limit, which makes valgrind - angry; this workaround removes some padding from the buffer - size */ - nbytes -= PADDING; - - AVProbeData avpd = { - .buf = buffer, - .buf_size = nbytes, - .filename = is->uri, - }; - - AVInputFormat *format = av_probe_input_format(&avpd, true); - g_free(buffer); - - return format; -} - static void libav_decode(struct decoder *decoder, struct input_stream *input) { LibavDecContext s = { .decoder = decoder }; - AVInputFormat *input_format; int ret; - input_format = libav_probe(decoder, input); - if (input_format == NULL) - return; - - g_debug("detected input format '%s' (%s)", - input_format->name, input_format->long_name); - s.decoder = decoder; ret = mpd_libav_stream_open(&s, input); if (ret < 0) { @@ -344,13 +310,16 @@ static void libav_decode(struct decoder *decoder, struct input_stream *input) //ffmpeg works with ours "fileops" helper AVFormatContext *format_context = NULL; - if (mpd_libav_open_input(&format_context, s.io, input->uri, - input_format) != 0) { + if (mpd_libav_open_input(&format_context, s.io, input->uri, NULL) != 0) { g_warning("Open failed\n"); mpd_libav_stream_close(&s); return; } + g_debug("Successfully opened input stream '%s', detected input format '%s' (%s)", + input->uri, format_context->iformat->name, format_context->iformat->long_name); + + const int find_result = avformat_find_stream_info(format_context, NULL); if (find_result < 0) { @@ -452,6 +421,40 @@ static void libav_decode(struct decoder *decoder, struct input_stream *input) mpd_libav_stream_close(&s); } +static AVInputFormat *libav_probe(struct decoder *decoder, struct input_stream *is) +{ + enum { + BUFFER_SIZE = 16384, + PADDING = 16, + }; + + unsigned char *buffer = g_malloc(BUFFER_SIZE); + size_t nbytes = decoder_read(decoder, is, buffer, BUFFER_SIZE); + if (nbytes <= PADDING || + !input_stream_lock_seek(is, 0, SEEK_SET, NULL)) { + g_free(buffer); + return NULL; + } + + /* some ffmpeg parsers (e.g. ac3_parser.c) read a few bytes + beyond the declared buffer limit, which makes valgrind + angry; this workaround removes some padding from the buffer + size */ + nbytes -= PADDING; + + AVProbeData avpd = { + .buf = buffer, + .buf_size = nbytes, + .filename = is->uri, + }; + + AVInputFormat *format = av_probe_input_format(&avpd, true); + g_free(buffer); + + return format; +} + + //no tag reading in ffmpeg, check if playable static bool libav_scan_stream(struct input_stream *is, -- cgit v1.2.3