libavformat API usage: use avformat_close_input() instead of av_close_input_file()
[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 "DNA_userdef_types.h"
50 #include "BKE_global.h"
51
52 #include "imbuf.h"
53 #include "IMB_imbuf_types.h"
54 #include "IMB_imbuf.h"
55 #include "IMB_filetype.h"
56
57 #include "IMB_anim.h"
58
59 #ifdef WITH_QUICKTIME
60 #include "quicktime_import.h"
61 #endif
62
63 #ifdef WITH_FFMPEG
64 #include <libavcodec/avcodec.h>
65 #include <libavformat/avformat.h>
66 #include <libavdevice/avdevice.h>
67 #include <libavutil/log.h>
68
69 #include "ffmpeg_compat.h"
70
71 #endif
72
73 #define UTIL_DEBUG 0
74
75 const char *imb_ext_image[] = {
76         ".png",
77         ".tga",
78         ".bmp",
79         ".jpg", ".jpeg",
80         ".sgi", ".rgb", ".rgba",
81 #ifdef WITH_TIFF
82         ".tif", ".tiff", ".tx",
83 #endif
84 #ifdef WITH_OPENJPEG
85         ".jp2",
86         ".j2c",
87 #endif
88 #ifdef WITH_HDR
89         ".hdr",
90 #endif
91 #ifdef WITH_DDS
92         ".dds",
93 #endif
94 #ifdef WITH_CINEON
95         ".dpx",
96         ".cin",
97 #endif
98 #ifdef WITH_OPENEXR
99         ".exr",
100 #endif
101 #ifdef WITH_OPENIMAGEIO
102         ".psd", ".pdd", ".psb",
103 #endif
104         NULL
105 };
106
107 const char *imb_ext_image_filepath_only[] = {
108 #ifdef WITH_OPENIMAGEIO
109         ".psd", ".pdd", ".psb",
110 #endif
111         NULL
112 };
113
114 const char *imb_ext_image_qt[] = {
115         ".gif",
116         ".psd",
117         ".pct", ".pict",
118         ".pntg",
119         ".qtif",
120         NULL
121 };
122
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
134 const char *imb_ext_movie[] = {
135         ".avi",
136         ".flc",
137         ".mov",
138         ".movie",
139         ".mp4",
140         ".m4v",
141         ".m2v",
142         ".m2t",
143         ".m2ts",
144         ".mts",
145         ".ts",
146         ".mv",
147         ".avs",
148         ".wmv",
149         ".ogv",
150         ".ogg",
151         ".r3d",
152         ".dv",
153         ".mpeg",
154         ".mpg",
155         ".mpg2",
156         ".vob",
157         ".mkv",
158         ".flv",
159         ".divx",
160         ".xvid",
161         ".mxf",
162         ".webm",
163         NULL
164 };
165
166 /* sort of wrong being here... */
167 const char *imb_ext_audio[] = {
168         ".wav",
169         ".ogg",
170         ".oga",
171         ".mp3",
172         ".mp2",
173         ".ac3",
174         ".aac",
175         ".flac",
176         ".wma",
177         ".eac3",
178         ".aif",
179         ".aiff",
180         ".m4a",
181         NULL
182 };
183
184 static int IMB_ispic_name(const char *name)
185 {
186         /* increased from 32 to 64 because of the bitmaps header size */
187 #define HEADER_SIZE 64
188
189         unsigned char buf[HEADER_SIZE];
190         ImFileType *type;
191         struct stat st;
192         int fp;
193
194         if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
195         
196         if (BLI_stat(name, &st) == -1)
197                 return FALSE;
198         if (((st.st_mode) & S_IFMT) != S_IFREG)
199                 return FALSE;
200
201         if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) < 0)
202                 return FALSE;
203
204         memset(buf, 0, sizeof(buf));
205         if (read(fp, buf, HEADER_SIZE) <= 0) {
206                 close(fp);
207                 return FALSE;
208         }
209
210         close(fp);
211
212         /* XXX move this exception */
213         if ((BIG_LONG(((int *)buf)[0]) & 0xfffffff0) == 0xffd8ffe0)
214                 return JPG;
215
216         for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
217                 if (type->is_a) {
218                         if (type->is_a(buf)) {
219                                 return type->filetype;
220                         }
221                 }
222                 else if (type->is_a_filepath) {
223                         if (type->is_a_filepath(name)) {
224                                 return type->filetype;
225                         }
226                 }
227         }
228
229         return FALSE;
230
231 #undef HEADER_SIZE
232 }
233
234 int IMB_ispic(const char *filename)
235 {
236         if (U.uiflag & USER_FILTERFILEEXTS) {
237                 if ((BLI_testextensie_array(filename, imb_ext_image)) ||
238                     (G.have_quicktime && BLI_testextensie_array(filename, imb_ext_image_qt)))
239                 {
240                         return IMB_ispic_name(filename);
241                 }
242                 else {
243                         return FALSE;
244                 }
245         }
246         else { /* no FILTERFILEEXTS */
247                 return IMB_ispic_name(filename);
248         }
249 }
250
251
252
253 static int isavi(const char *name)
254 {
255 #ifdef WITH_AVI
256         return AVI_is_avi(name);
257 #else
258         (void)name;
259         return FALSE;
260 #endif
261 }
262
263 #ifdef WITH_QUICKTIME
264 static int isqtime(const char *name)
265 {
266         return anim_is_quicktime(name);
267 }
268 #endif
269
270 #ifdef WITH_FFMPEG
271
272 #ifdef _MSC_VER
273 #define va_copy(dst, src) ((dst) = (src))
274 #endif
275
276 /* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
277 #ifdef __GNUC__
278 #  pragma GCC diagnostic push
279 #  pragma GCC diagnostic ignored "-Wmissing-format-attribute"
280 #endif
281
282 static char ffmpeg_last_error[1024];
283
284 static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
285 {
286         if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
287                 size_t n;
288                 va_list args_cpy;
289
290                 va_copy(args_cpy, arg);
291                 n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy);
292                 va_end(args_cpy);
293
294                 /* strip trailing \n */
295                 ffmpeg_last_error[n - 1] = '\0';
296         }
297
298         if (G.debug & G_DEBUG_FFMPEG) {
299                 /* call default logger to print all message to console */
300                 av_log_default_callback(ptr, level, format, arg);
301         }
302 }
303
304 #ifdef __GNUC__
305 #  pragma GCC diagnostic pop
306 #endif
307
308 void IMB_ffmpeg_init(void)
309 {
310         av_register_all();
311         avdevice_register_all();
312
313         ffmpeg_last_error[0] = '\0';
314
315         if (G.debug & G_DEBUG_FFMPEG)
316                 av_log_set_level(AV_LOG_DEBUG);
317
318         /* set own callback which could store last error to report to UI */
319         av_log_set_callback(ffmpeg_log_callback);
320 }
321
322 const char *IMB_ffmpeg_last_error(void)
323 {
324         return ffmpeg_last_error;
325 }
326
327 static int isffmpeg(const char *filename)
328 {
329         AVFormatContext *pFormatCtx = NULL;
330         unsigned int i;
331         int videoStream;
332         AVCodec *pCodec;
333         AVCodecContext *pCodecCtx;
334
335         if (BLI_testextensie(filename, ".swf") ||
336             BLI_testextensie(filename, ".jpg") ||
337             BLI_testextensie(filename, ".png") ||
338             BLI_testextensie(filename, ".dds") ||
339             BLI_testextensie(filename, ".tga") ||
340             BLI_testextensie(filename, ".bmp") ||
341             BLI_testextensie(filename, ".tif") ||
342             BLI_testextensie(filename, ".exr") ||
343             BLI_testextensie(filename, ".cin") ||
344             BLI_testextensie(filename, ".wav"))
345         {
346                 return 0;
347         }
348
349         if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
350                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
351                 return 0;
352         }
353
354         if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
355                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
356                 avformat_close_input(&pFormatCtx);
357                 return 0;
358         }
359
360         if (UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
361
362
363         /* Find the first video stream */
364         videoStream = -1;
365         for (i = 0; i < pFormatCtx->nb_streams; i++)
366                 if (pFormatCtx->streams[i] &&
367                     pFormatCtx->streams[i]->codec &&
368                     (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
369                 {
370                         videoStream = i;
371                         break;
372                 }
373
374         if (videoStream == -1) {
375                 avformat_close_input(&pFormatCtx);
376                 return 0;
377         }
378
379         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
380
381         /* Find the decoder for the video stream */
382         pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
383         if (pCodec == NULL) {
384                 avformat_close_input(&pFormatCtx);
385                 return 0;
386         }
387
388         if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
389                 avformat_close_input(&pFormatCtx);
390                 return 0;
391         }
392
393         avcodec_close(pCodecCtx);
394         avformat_close_input(&pFormatCtx);
395
396         return 1;
397 }
398 #endif
399
400 #ifdef WITH_REDCODE
401 static int isredcode(const char *filename)
402 {
403         struct redcode_handle *h = redcode_open(filename);
404         if (!h) {
405                 return 0;
406         }
407         redcode_close(h);
408         return 1;
409 }
410
411 #endif
412
413 int imb_get_anim_type(const char *name)
414 {
415         int type;
416         struct stat st;
417
418         if (UTIL_DEBUG) printf("in getanimtype: %s\n", name);
419
420 #ifndef _WIN32
421 #   ifdef WITH_QUICKTIME
422         if (isqtime(name)) return (ANIM_QTIME);
423 #   endif
424 #   ifdef WITH_FFMPEG
425         /* stat test below fails on large files > 4GB */
426         if (isffmpeg(name)) return (ANIM_FFMPEG);
427 #   endif
428         if (BLI_stat(name, &st) == -1) return(0);
429         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
430
431         if (isavi(name)) return (ANIM_AVI);
432
433         if (ismovie(name)) return (ANIM_MOVIE);
434 #else
435         if (BLI_stat(name, &st) == -1) return(0);
436         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
437
438         if (ismovie(name)) return (ANIM_MOVIE);
439 #   ifdef WITH_QUICKTIME
440         if (isqtime(name)) return (ANIM_QTIME);
441 #   endif
442 #   ifdef WITH_FFMPEG
443         if (isffmpeg(name)) return (ANIM_FFMPEG);
444 #   endif
445
446
447         if (isavi(name)) return (ANIM_AVI);
448 #endif
449 #ifdef WITH_REDCODE
450         if (isredcode(name)) return (ANIM_REDCODE);
451 #endif
452         type = IMB_ispic(name);
453         if (type) {
454                 return ANIM_SEQUENCE;
455         }
456
457         return ANIM_NONE;
458 }
459  
460 int IMB_isanim(const char *filename)
461 {
462         int type;
463         
464         if (U.uiflag & USER_FILTERFILEEXTS) {
465                 if (G.have_quicktime) {
466                         if (BLI_testextensie_array(filename, imb_ext_movie_qt)) {       
467                                 type = imb_get_anim_type(filename);
468                         }
469                         else {
470                                 return(FALSE);
471                         }
472                 }
473                 else { /* no quicktime */
474                         if (BLI_testextensie_array(filename, imb_ext_movie)) {
475                                 type = imb_get_anim_type(filename);
476                         }
477                         else {
478                                 return(FALSE);
479                         }
480                 }
481         }
482         else { /* no FILTERFILEEXTS */
483                 type = imb_get_anim_type(filename);
484         }
485         
486         return (type && type != ANIM_SEQUENCE);
487 }