2 * GeeXboX Valhalla: tiny media scanner API.
3 * Copyright (C) 2009 Mathieu Schroeter <mathieu.schroeter@gamesover.ch>
5 * This file is part of libvalhalla.
7 * libvalhalla is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * libvalhalla is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with libvalhalla; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <libavformat/avformat.h>
28 #include "valhalla_internals.h"
30 #include "lavf_utils.h"
32 static const struct fileext_s {
67 { "ingenient", "cgi" },
68 { "matroska", "mkv" },
70 { "mov,mp4,m4a,3gp,3g2,mj2", "3g2" },
71 { "mov,mp4,m4a,3gp,3g2,mj2", "3gp" },
72 { "mov,mp4,m4a,3gp,3g2,mj2", "m4a" },
73 { "mov,mp4,m4a,3gp,3g2,mj2", "mov" },
74 { "mov,mp4,m4a,3gp,3g2,mj2", "mp4" },
75 { "mov,mp4,m4a,3gp,3g2,mj2", "mj2" },
76 { "mpeg1video", "m1v" },
77 { "mpeg1video", "mpeg" },
78 { "mpeg1video", "mpg" },
83 { "rawvideo", "cif" },
84 { "rawvideo", "qcif" },
85 { "rawvideo", "rgb" },
86 { "rawvideo", "yuv" },
90 { "yuv4mpegpipe", "y4m" },
95 vh_lavf_utils_fmtname_get (const char *suffix)
97 const struct fileext_s *it;
102 for (it = g_fileext; it->fmtname; it++)
103 if (!strcasecmp (suffix, it->suffix))
110 suffix_fmt_guess (const char *file)
117 it = strrchr (file, '.');
121 return vh_lavf_utils_fmtname_get (it);
124 #define PROBE_BUF_MIN 2048
125 #define PROBE_BUF_MAX (1 << 20)
128 * This function is fully inspired of (libavformat/utils.c v52.28.0
129 * "av_open_input_file()") to probe data in order to test if *ftm argument
130 * is the right fmt or not.
132 * The original function from avformat "av_probe_input_format2()" is really
133 * slow because it probes the fmt of _all_ demuxers for each probe_data
134 * buffer. Here, the test is only for _one_ fmt and returns the score
135 * (if > score_max) provided by fmt->probe().
137 * WARNING: this function depends of some internal behaviours of libavformat
138 * and can be "broken" with future versions of FFmpeg.
141 lavf_utils_probe (AVInputFormat *fmt, const char *file)
148 if (!fmt->read_probe)
151 p_data.filename = file;
155 /* No file should be opened here. */
156 if (fmt->flags & AVFMT_NOFILE)
158 rc = fmt->read_probe (&p_data);
162 fd = fopen (file, "rb");
166 for (p_size = PROBE_BUF_MIN; p_size <= PROBE_BUF_MAX; p_size <<= 1)
169 int score_max = p_size < PROBE_BUF_MAX ? AVPROBE_SCORE_MAX / 4 : 0;
171 p_data.buf = realloc (p_data.buf, p_size + AVPROBE_PADDING_SIZE);
175 p_data.buf_size = fread (p_data.buf, 1, p_size, fd);
176 if (p_data.buf_size != p_size) /* EOF is reached? */
179 memset (p_data.buf + p_data.buf_size, 0, AVPROBE_PADDING_SIZE);
181 if (fseek (fd, 0, SEEK_SET))
184 score = fmt->read_probe (&p_data);
185 if (score > score_max)
201 vh_lavf_utils_open_input_file (const char *file)
205 AVFormatContext *ctx;
206 AVFormatParameters ap;
207 AVInputFormat *fmt = NULL;
209 ctx = avformat_alloc_context ();
213 ctx->flags |= AVFMT_FLAG_IGNIDX;
216 * Try a format in function of the suffix.
217 * We gain a lot of speed if the fmt is already the right.
219 name = suffix_fmt_guess (file);
221 fmt = av_find_input_format (name);
225 int score = lavf_utils_probe (fmt, file);
226 vh_log (VALHALLA_MSG_VERBOSE,
227 "Probe score (%i) [%s] : %s", score, name, file);
228 if (!score) /* Bad score? */
232 memset (&ap, 0, sizeof (ap));
233 ap.prealloced_context = 1;
235 res = av_open_input_file (&ctx, file, fmt, 0, &ap);
238 vh_log (VALHALLA_MSG_WARNING,
239 "FFmpeg can't open file (%i) : %s", res, file);