Fix T39186: Matroska audio support (mka, mkv without video stream)
[blender.git] / source / blender / imbuf / intern / util.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * util.c
27  *
28  */
29
30 /** \file blender/imbuf/intern/util.c
31  *  \ingroup imbuf
32  */
33
34
35 #ifdef _WIN32
36 #  include <io.h>
37 #  define open _open
38 #  define read _read
39 #  define close _close
40 #endif
41
42 #include <stdlib.h>
43
44 #include "BLI_utildefines.h"
45 #include "BLI_path_util.h"
46 #include "BLI_fileops.h"
47 #include "BLI_string.h"
48
49 #include "BKE_global.h"
50
51 #include "imbuf.h"
52 #include "IMB_imbuf_types.h"
53 #include "IMB_imbuf.h"
54 #include "IMB_filetype.h"
55
56 #include "IMB_anim.h"
57
58 #ifdef WITH_QUICKTIME
59 #include "quicktime_import.h"
60 #endif
61
62 #ifdef WITH_FFMPEG
63 #include <libavcodec/avcodec.h>
64 #include <libavformat/avformat.h>
65 #include <libavdevice/avdevice.h>
66 #include <libavutil/log.h>
67
68 #include "ffmpeg_compat.h"
69
70 #endif
71
72 #define UTIL_DEBUG 0
73
74 const char *imb_ext_image[] = {
75         ".png",
76         ".tga",
77         ".bmp",
78         ".jpg", ".jpeg",
79         ".sgi", ".rgb", ".rgba",
80 #ifdef WITH_TIFF
81         ".tif", ".tiff", ".tx",
82 #endif
83 #ifdef WITH_OPENJPEG
84         ".jp2",
85         ".j2c",
86 #endif
87 #ifdef WITH_HDR
88         ".hdr",
89 #endif
90 #ifdef WITH_DDS
91         ".dds",
92 #endif
93 #ifdef WITH_CINEON
94         ".dpx",
95         ".cin",
96 #endif
97 #ifdef WITH_OPENEXR
98         ".exr",
99 #endif
100 #ifdef WITH_OPENIMAGEIO
101         ".psd", ".pdd", ".psb",
102 #endif
103         NULL
104 };
105
106 const char *imb_ext_image_filepath_only[] = {
107 #ifdef WITH_OPENIMAGEIO
108         ".psd", ".pdd", ".psb",
109 #endif
110         NULL
111 };
112
113 const char *imb_ext_image_qt[] = {
114         ".gif",
115         ".psd",
116         ".pct", ".pict",
117         ".pntg",
118         ".qtif",
119         NULL
120 };
121
122 #if 0  /* UNUSED */
123 const char *imb_ext_movie_qt[] = {
124         ".avi",   
125         ".flc",   
126         ".dv",    
127         ".r3d",   
128         ".mov",   
129         ".movie", 
130         ".mv",
131         NULL
132 };
133 #endif
134
135 const char *imb_ext_movie[] = {
136         ".avi",
137         ".flc",
138         ".mov",
139         ".movie",
140         ".mp4",
141         ".m4v",
142         ".m2v",
143         ".m2t",
144         ".m2ts",
145         ".mts",
146         ".ts",
147         ".mv",
148         ".avs",
149         ".wmv",
150         ".ogv",
151         ".ogg",
152         ".r3d",
153         ".dv",
154         ".mpeg",
155         ".mpg",
156         ".mpg2",
157         ".vob",
158         ".mkv",
159         ".flv",
160         ".divx",
161         ".xvid",
162         ".mxf",
163         ".webm",
164         NULL
165 };
166
167 /* sort of wrong being here... */
168 const char *imb_ext_audio[] = {
169         ".wav",
170         ".ogg",
171         ".oga",
172         ".mp3",
173         ".mp2",
174         ".ac3",
175         ".aac",
176         ".flac",
177         ".wma",
178         ".eac3",
179         ".aif",
180         ".aiff",
181         ".m4a",
182         ".mka",
183         NULL
184 };
185
186 int IMB_ispic(const char *name)
187 {
188         /* increased from 32 to 64 because of the bitmaps header size */
189 #define HEADER_SIZE 64
190
191         unsigned char buf[HEADER_SIZE];
192         ImFileType *type;
193         struct stat st;
194         int fp;
195
196         if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
197         
198         if (BLI_stat(name, &st) == -1)
199                 return FALSE;
200         if (((st.st_mode) & S_IFMT) != S_IFREG)
201                 return FALSE;
202
203         if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) < 0)
204                 return FALSE;
205
206         memset(buf, 0, sizeof(buf));
207         if (read(fp, buf, HEADER_SIZE) <= 0) {
208                 close(fp);
209                 return FALSE;
210         }
211
212         close(fp);
213
214         /* XXX move this exception */
215         if ((BIG_LONG(((int *)buf)[0]) & 0xfffffff0) == 0xffd8ffe0)
216                 return JPG;
217
218         for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
219                 if (type->is_a) {
220                         if (type->is_a(buf)) {
221                                 return type->filetype;
222                         }
223                 }
224                 else if (type->is_a_filepath) {
225                         if (type->is_a_filepath(name)) {
226                                 return type->filetype;
227                         }
228                 }
229         }
230
231         return FALSE;
232
233 #undef HEADER_SIZE
234 }
235
236
237 static int isavi(const char *name)
238 {
239 #ifdef WITH_AVI
240         return AVI_is_avi(name);
241 #else
242         (void)name;
243         return FALSE;
244 #endif
245 }
246
247 #ifdef WITH_QUICKTIME
248 static int isqtime(const char *name)
249 {
250         return anim_is_quicktime(name);
251 }
252 #endif
253
254 #ifdef WITH_FFMPEG
255
256 #if defined(_MSC_VER) && _MSC_VER < 1800
257 #define va_copy(dst, src) ((dst) = (src))
258 #endif
259
260 /* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
261 #ifdef __GNUC__
262 #  pragma GCC diagnostic push
263 #  pragma GCC diagnostic ignored "-Wmissing-format-attribute"
264 #endif
265
266 static char ffmpeg_last_error[1024];
267
268 static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
269 {
270         if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
271                 size_t n;
272                 va_list args_cpy;
273
274                 va_copy(args_cpy, arg);
275                 n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy);
276                 va_end(args_cpy);
277
278                 /* strip trailing \n */
279                 ffmpeg_last_error[n - 1] = '\0';
280         }
281
282         if (G.debug & G_DEBUG_FFMPEG) {
283                 /* call default logger to print all message to console */
284                 av_log_default_callback(ptr, level, format, arg);
285         }
286 }
287
288 #ifdef __GNUC__
289 #  pragma GCC diagnostic pop
290 #endif
291
292 void IMB_ffmpeg_init(void)
293 {
294         av_register_all();
295         avdevice_register_all();
296
297         ffmpeg_last_error[0] = '\0';
298
299         if (G.debug & G_DEBUG_FFMPEG)
300                 av_log_set_level(AV_LOG_DEBUG);
301
302         /* set own callback which could store last error to report to UI */
303         av_log_set_callback(ffmpeg_log_callback);
304 }
305
306 const char *IMB_ffmpeg_last_error(void)
307 {
308         return ffmpeg_last_error;
309 }
310
311 static int isffmpeg(const char *filename)
312 {
313         AVFormatContext *pFormatCtx = NULL;
314         unsigned int i;
315         int videoStream;
316         AVCodec *pCodec;
317         AVCodecContext *pCodecCtx;
318
319         if (BLI_testextensie_n(
320                 filename,
321                 ".swf", ".jpg", ".png", ".dds", ".tga", ".bmp", ".tif", ".exr", ".cin", ".wav", NULL))
322         {
323                 return 0;
324         }
325
326         if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
327                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
328                 return 0;
329         }
330
331         if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
332                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
333                 avformat_close_input(&pFormatCtx);
334                 return 0;
335         }
336
337         if (UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
338
339
340         /* Find the first video stream */
341         videoStream = -1;
342         for (i = 0; i < pFormatCtx->nb_streams; i++)
343                 if (pFormatCtx->streams[i] &&
344                     pFormatCtx->streams[i]->codec &&
345                     (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
346                 {
347                         videoStream = i;
348                         break;
349                 }
350
351         if (videoStream == -1) {
352                 avformat_close_input(&pFormatCtx);
353                 return 0;
354         }
355
356         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
357
358         /* Find the decoder for the video stream */
359         pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
360         if (pCodec == NULL) {
361                 avformat_close_input(&pFormatCtx);
362                 return 0;
363         }
364
365         if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
366                 avformat_close_input(&pFormatCtx);
367                 return 0;
368         }
369
370         avcodec_close(pCodecCtx);
371         avformat_close_input(&pFormatCtx);
372
373         return 1;
374 }
375 #endif
376
377 #ifdef WITH_REDCODE
378 static int isredcode(const char *filename)
379 {
380         struct redcode_handle *h = redcode_open(filename);
381         if (!h) {
382                 return 0;
383         }
384         redcode_close(h);
385         return 1;
386 }
387
388 #endif
389
390 int imb_get_anim_type(const char *name)
391 {
392         int type;
393         struct stat st;
394
395         if (UTIL_DEBUG) printf("in getanimtype: %s\n", name);
396
397 #ifndef _WIN32
398 #   ifdef WITH_QUICKTIME
399         if (isqtime(name)) return (ANIM_QTIME);
400 #   endif
401 #   ifdef WITH_FFMPEG
402         /* stat test below fails on large files > 4GB */
403         if (isffmpeg(name)) return (ANIM_FFMPEG);
404 #   endif
405         if (BLI_stat(name, &st) == -1) return(0);
406         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
407
408         if (isavi(name)) return (ANIM_AVI);
409
410         if (ismovie(name)) return (ANIM_MOVIE);
411 #else
412         if (BLI_stat(name, &st) == -1) return(0);
413         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
414
415         if (ismovie(name)) return (ANIM_MOVIE);
416 #   ifdef WITH_QUICKTIME
417         if (isqtime(name)) return (ANIM_QTIME);
418 #   endif
419 #   ifdef WITH_FFMPEG
420         if (isffmpeg(name)) return (ANIM_FFMPEG);
421 #   endif
422
423
424         if (isavi(name)) return (ANIM_AVI);
425 #endif
426 #ifdef WITH_REDCODE
427         if (isredcode(name)) return (ANIM_REDCODE);
428 #endif
429         type = IMB_ispic(name);
430         if (type) {
431                 return ANIM_SEQUENCE;
432         }
433
434         return ANIM_NONE;
435 }
436  
437 bool IMB_isanim(const char *filename)
438 {
439         int type;
440         
441         type = imb_get_anim_type(filename);
442         
443         return (type && type != ANIM_SEQUENCE);
444 }