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:
parent
0265c34bed
commit
375a09d6f6
@ -160,11 +160,53 @@ append_uri_suffix(struct ffmpeg_stream *stream, const char *uri)
|
||||
g_free(base);
|
||||
}
|
||||
|
||||
static AVInputFormat *
|
||||
ffmpeg_probe(struct decoder *decoder, struct input_stream *is,
|
||||
const char *uri)
|
||||
{
|
||||
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)) {
|
||||
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 = uri,
|
||||
};
|
||||
|
||||
AVInputFormat *format = av_probe_input_format(&avpd, true);
|
||||
g_free(buffer);
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static bool
|
||||
ffmpeg_helper(const char *uri, struct input_stream *input,
|
||||
ffmpeg_helper(const char *uri,
|
||||
struct decoder *decoder, struct input_stream *input,
|
||||
bool (*callback)(struct ffmpeg_context *ctx),
|
||||
struct ffmpeg_context *ctx)
|
||||
{
|
||||
AVInputFormat *input_format = ffmpeg_probe(decoder, input, uri);
|
||||
if (input_format == NULL)
|
||||
return false;
|
||||
|
||||
g_debug("detected input format '%s' (%s)",
|
||||
input_format->name, input_format->long_name);
|
||||
|
||||
AVFormatContext *format_context;
|
||||
AVCodecContext *codec_context;
|
||||
AVCodec *codec;
|
||||
@ -185,7 +227,8 @@ ffmpeg_helper(const char *uri, struct input_stream *input,
|
||||
}
|
||||
|
||||
//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 false;
|
||||
}
|
||||
@ -377,7 +420,7 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
||||
ctx.decoder = decoder;
|
||||
|
||||
char *uri = decoder_get_uri(decoder);
|
||||
ffmpeg_helper(uri, input,
|
||||
ffmpeg_helper(uri, decoder, input,
|
||||
ffmpeg_decode_internal, &ctx);
|
||||
g_free(uri);
|
||||
}
|
||||
@ -465,7 +508,7 @@ static struct tag *ffmpeg_tag(const char *file)
|
||||
ctx.decoder = NULL;
|
||||
ctx.tag = tag_new();
|
||||
|
||||
ret = ffmpeg_helper(file, &input, ffmpeg_tag_internal, &ctx);
|
||||
ret = ffmpeg_helper(file, NULL, &input, ffmpeg_tag_internal, &ctx);
|
||||
if (!ret) {
|
||||
tag_free(ctx.tag);
|
||||
ctx.tag = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user