aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder/ffmpeg_decoder_plugin.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2010-06-30 20:32:29 +0200
committerMax Kellermann <max@duempel.org>2010-07-19 22:59:59 +0200
commitb2e3c0757b2507db727d5b722b5043d3f98c7ee5 (patch)
tree6c6b2b52587b227ed91c26ec82f7b372889f585b /src/decoder/ffmpeg_decoder_plugin.c
parent0fc0196dba684e1aac2752a64babffad62f84356 (diff)
downloadmpd-b2e3c0757b2507db727d5b722b5043d3f98c7ee5.tar.gz
mpd-b2e3c0757b2507db727d5b722b5043d3f98c7ee5.tar.xz
mpd-b2e3c0757b2507db727d5b722b5043d3f98c7ee5.zip
decoder/ffmpeg: manual format probing
Use the libavformat function av_probe_input_format() to probe the AVInputFormat, instead of letting av_open_input_file() do it implicitly. We will switch to av_open_input_stream() very soon, which does not have the probing code. Loosely based on a patch from Jasper St. Pierre.
Diffstat (limited to '')
-rw-r--r--src/decoder/ffmpeg_decoder_plugin.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c
index 68c376211..94b60ecb5 100644
--- a/src/decoder/ffmpeg_decoder_plugin.c
+++ b/src/decoder/ffmpeg_decoder_plugin.c
@@ -277,9 +277,49 @@ ffmpeg_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context)
#endif
}
+static AVInputFormat *
+ffmpeg_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_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
ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
{
+ AVInputFormat *input_format = ffmpeg_probe(decoder, input);
+ if (input_format == NULL)
+ return;
+
+ g_debug("detected input format '%s' (%s)",
+ input_format->name, input_format->long_name);
+
struct ffmpeg_stream stream = {
.url = "mpd://X", /* only the mpd:// prefix matters */
.decoder = decoder,
@@ -294,7 +334,8 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
append_uri_suffix(&stream, input->uri);
//ffmpeg works with ours "fileops" helper
- if (av_open_input_file(&format_context, stream.url, NULL, 0, NULL) != 0) {
+ if (av_open_input_file(&format_context, stream.url, input_format,
+ 0, NULL) != 0) {
g_warning("Open failed\n");
return;
}
@@ -425,6 +466,10 @@ ffmpeg_copy_metadata(struct tag *tag, AVMetadata *m,
static struct tag *
ffmpeg_stream_tag(struct input_stream *is)
{
+ AVInputFormat *input_format = ffmpeg_probe(NULL, is);
+ if (input_format == NULL)
+ return NULL;
+
struct ffmpeg_stream stream = {
.url = "mpd://X", /* only the mpd:// prefix matters */
.decoder = NULL,
@@ -435,7 +480,7 @@ ffmpeg_stream_tag(struct input_stream *is)
append_uri_suffix(&stream, is->uri);
AVFormatContext *f;
- if (av_open_input_file(&f, stream.url, NULL, 0, NULL) != 0)
+ if (av_open_input_file(&f, stream.url, input_format, 0, NULL) != 0)
return NULL;
if (av_find_stream_info(f) < 0) {