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.
This commit is contained in:
Max Kellermann 2010-06-30 20:32:29 +02:00
parent 0fc0196dba
commit b2e3c0757b

View File

@ -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) {