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
0fc0196dba
commit
b2e3c0757b
@ -277,9 +277,49 @@ ffmpeg_sample_format(G_GNUC_UNUSED const AVCodecContext *codec_context)
|
|||||||
#endif
|
#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
|
static void
|
||||||
ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
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 = {
|
struct ffmpeg_stream stream = {
|
||||||
.url = "mpd://X", /* only the mpd:// prefix matters */
|
.url = "mpd://X", /* only the mpd:// prefix matters */
|
||||||
.decoder = decoder,
|
.decoder = decoder,
|
||||||
@ -294,7 +334,8 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input)
|
|||||||
append_uri_suffix(&stream, input->uri);
|
append_uri_suffix(&stream, input->uri);
|
||||||
|
|
||||||
//ffmpeg works with ours "fileops" helper
|
//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");
|
g_warning("Open failed\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -425,6 +466,10 @@ ffmpeg_copy_metadata(struct tag *tag, AVMetadata *m,
|
|||||||
static struct tag *
|
static struct tag *
|
||||||
ffmpeg_stream_tag(struct input_stream *is)
|
ffmpeg_stream_tag(struct input_stream *is)
|
||||||
{
|
{
|
||||||
|
AVInputFormat *input_format = ffmpeg_probe(NULL, is);
|
||||||
|
if (input_format == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
struct ffmpeg_stream stream = {
|
struct ffmpeg_stream stream = {
|
||||||
.url = "mpd://X", /* only the mpd:// prefix matters */
|
.url = "mpd://X", /* only the mpd:// prefix matters */
|
||||||
.decoder = NULL,
|
.decoder = NULL,
|
||||||
@ -435,7 +480,7 @@ ffmpeg_stream_tag(struct input_stream *is)
|
|||||||
append_uri_suffix(&stream, is->uri);
|
append_uri_suffix(&stream, is->uri);
|
||||||
|
|
||||||
AVFormatContext *f;
|
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;
|
return NULL;
|
||||||
|
|
||||||
if (av_find_stream_info(f) < 0) {
|
if (av_find_stream_info(f) < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user