Some FFmpeg changes
[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_path_util.h"
45 #include "BLI_fileops.h"
46 #include "BLI_utildefines.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 #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         NULL
101 };
102
103 const char *imb_ext_image_qt[] = {
104         ".gif",
105         ".psd",
106         ".pct", ".pict",
107         ".pntg",
108         ".qtif",
109         NULL
110 };
111
112 const char *imb_ext_movie[] = {
113         ".avi",
114         ".flc",
115         ".mov",
116         ".movie",
117         ".mp4",
118         ".m4v",
119         ".m2v",
120         ".m2t",
121         ".m2ts",
122         ".mts",
123         ".mv",
124         ".avs",
125         ".wmv",
126         ".ogv",
127         ".dv",
128         ".mpeg",
129         ".mpg",
130         ".mpg2",
131         ".vob",
132         ".mkv",
133         ".flv",
134         ".divx",
135         ".xvid",
136         ".mxf",
137         NULL
138 };
139
140 /* sort of wrong being here... */
141 const char *imb_ext_audio[] = {
142         ".wav",
143         ".ogg",
144         ".oga",
145         ".mp3",
146         ".mp2",
147         ".ac3",
148         ".aac",
149         ".flac",
150         ".wma",
151         ".eac3",
152         ".aif",
153         ".aiff",
154         ".m4a",
155         NULL
156 };
157
158 static int IMB_ispic_name(const char *name)
159 {
160         ImFileType *type;
161         struct stat st;
162         int fp, buf[10];
163
164         if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
165         
166         if (stat(name, &st) == -1)
167                 return FALSE;
168         if (((st.st_mode) & S_IFMT) != S_IFREG)
169                 return FALSE;
170
171         if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) < 0)
172                 return FALSE;
173
174         if (read(fp, buf, 32) != 32) {
175                 close(fp);
176                 return FALSE;
177         }
178
179         close(fp);
180
181         /* XXX move this exception */
182         if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0)
183                 return JPG;
184
185         for (type = IMB_FILE_TYPES; type->is_a; type++)
186                 if (type->is_a((uchar *)buf))
187                         return type->filetype;
188
189         return FALSE;
190 }
191
192 int IMB_ispic(const char *filename)
193 {
194         if (U.uiflag & USER_FILTERFILEEXTS) {
195                 if ((BLI_testextensie_array(filename, imb_ext_image)) ||
196                     (G.have_quicktime && BLI_testextensie_array(filename, imb_ext_image_qt)))
197                 {
198                         return IMB_ispic_name(filename);
199                 }
200                 else {
201                         return FALSE;
202                 }
203         }
204         else { /* no FILTERFILEEXTS */
205                 return IMB_ispic_name(filename);
206         }
207 }
208
209
210
211 static int isavi(const char *name)
212 {
213         return AVI_is_avi(name);
214 }
215
216 #ifdef WITH_QUICKTIME
217 static int isqtime(const char *name)
218 {
219         return anim_is_quicktime(name);
220 }
221 #endif
222
223 #ifdef WITH_FFMPEG
224
225 static char ffmpeg_last_error[1024];
226
227 void silence_log_ffmpeg(int quiet)
228 {
229         if (quiet) {
230                 av_log_set_level(AV_LOG_QUIET);
231         }
232         else {
233                 av_log_set_level(AV_LOG_DEBUG);
234         }
235 }
236
237 void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
238 {
239         if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
240                 size_t n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, arg);
241
242                 /* strip trailing \n */
243                 ffmpeg_last_error[n - 1] = '\0';
244         }
245
246         /* call default logger to print all message to console */
247         av_log_default_callback(ptr, level, format, arg);
248 }
249
250 void IMB_ffmpeg_init(void)
251 {
252         av_register_all();
253         avdevice_register_all();
254
255         if ((G.debug & G_DEBUG_FFMPEG) == 0) {
256                 silence_log_ffmpeg(1);
257         }
258         else {
259                 silence_log_ffmpeg(0);
260         }
261
262         ffmpeg_last_error[0] = '\0';
263
264         /* set own callback which could store last error to report to UI */
265         av_log_set_callback(ffmpeg_log_callback);
266 }
267
268 const char *IMB_ffmpeg_last_error(void)
269 {
270         return ffmpeg_last_error;
271 }
272
273 static int isffmpeg(const char *filename)
274 {
275         AVFormatContext *pFormatCtx = NULL;
276         unsigned int i;
277         int videoStream;
278         AVCodec *pCodec;
279         AVCodecContext *pCodecCtx;
280
281         if (BLI_testextensie(filename, ".swf") ||
282             BLI_testextensie(filename, ".jpg") ||
283             BLI_testextensie(filename, ".png") ||
284             BLI_testextensie(filename, ".dds") ||
285             BLI_testextensie(filename, ".tga") ||
286             BLI_testextensie(filename, ".bmp") ||
287             BLI_testextensie(filename, ".exr") ||
288             BLI_testextensie(filename, ".cin") ||
289             BLI_testextensie(filename, ".wav"))
290         {
291                 return 0;
292         }
293
294         if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
295                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
296                 return 0;
297         }
298
299         if (av_find_stream_info(pFormatCtx) < 0) {
300                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
301                 av_close_input_file(pFormatCtx);
302                 return 0;
303         }
304
305         if (UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
306
307
308         /* Find the first video stream */
309         videoStream = -1;
310         for (i = 0; i < pFormatCtx->nb_streams; i++)
311                 if (pFormatCtx->streams[i] &&
312                     pFormatCtx->streams[i]->codec &&
313                     (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
314                 {
315                         videoStream = i;
316                         break;
317                 }
318
319         if (videoStream == -1) {
320                 av_close_input_file(pFormatCtx);
321                 return 0;
322         }
323
324         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
325
326         /* Find the decoder for the video stream */
327         pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
328         if (pCodec == NULL) {
329                 av_close_input_file(pFormatCtx);
330                 return 0;
331         }
332
333         if (avcodec_open(pCodecCtx, pCodec) < 0) {
334                 av_close_input_file(pFormatCtx);
335                 return 0;
336         }
337
338         avcodec_close(pCodecCtx);
339         av_close_input_file(pFormatCtx);
340
341         return 1;
342 }
343 #endif
344
345 #ifdef WITH_REDCODE
346 static int isredcode(const char *filename)
347 {
348         struct redcode_handle *h = redcode_open(filename);
349         if (!h) {
350                 return 0;
351         }
352         redcode_close(h);
353         return 1;
354 }
355
356 #endif
357
358 int imb_get_anim_type(const char *name)
359 {
360         int type;
361         struct stat st;
362
363         if (UTIL_DEBUG) printf("in getanimtype: %s\n", name);
364
365 #ifndef _WIN32
366 #   ifdef WITH_QUICKTIME
367         if (isqtime(name)) return (ANIM_QTIME);
368 #   endif
369 #   ifdef WITH_FFMPEG
370         /* stat test below fails on large files > 4GB */
371         if (isffmpeg(name)) return (ANIM_FFMPEG);
372 #   endif
373         if (BLI_stat(name, &st) == -1) return(0);
374         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
375
376         if (isavi(name)) return (ANIM_AVI);
377
378         if (ismovie(name)) return (ANIM_MOVIE);
379 #else
380         if (BLI_stat(name, &st) == -1) return(0);
381         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
382
383         if (ismovie(name)) return (ANIM_MOVIE);
384 #   ifdef WITH_QUICKTIME
385         if (isqtime(name)) return (ANIM_QTIME);
386 #   endif
387 #   ifdef WITH_FFMPEG
388         if (isffmpeg(name)) return (ANIM_FFMPEG);
389 #   endif
390
391
392         if (isavi(name)) return (ANIM_AVI);
393 #endif
394 #ifdef WITH_REDCODE
395         if (isredcode(name)) return (ANIM_REDCODE);
396 #endif
397         type = IMB_ispic(name);
398         if (type) {
399                 return ANIM_SEQUENCE;
400         }
401
402         return ANIM_NONE;
403 }
404  
405 int IMB_isanim(const char *filename)
406 {
407         int type;
408         
409         if (U.uiflag & USER_FILTERFILEEXTS) {
410                 if (G.have_quicktime) {
411                         if (BLI_testextensie(filename, ".avi")   ||
412                             BLI_testextensie(filename, ".flc")   ||
413                             BLI_testextensie(filename, ".dv")    ||
414                             BLI_testextensie(filename, ".r3d")   ||
415                             BLI_testextensie(filename, ".mov")   ||
416                             BLI_testextensie(filename, ".movie") ||
417                             BLI_testextensie(filename, ".mv"))
418                         {
419                                 type = imb_get_anim_type(filename);
420                         }
421                         else {
422                                 return(FALSE);                  
423                         }
424                 }
425                 else { /* no quicktime */
426                         if (BLI_testextensie(filename, ".avi") ||
427                             BLI_testextensie(filename, ".dv")  ||
428                             BLI_testextensie(filename, ".r3d") ||
429                             BLI_testextensie(filename, ".mv"))
430                         {
431                                 type = imb_get_anim_type(filename);
432                         }
433                         else {
434                                 return(FALSE);
435                         }
436                 }
437         }
438         else { /* no FILTERFILEEXTS */
439                 type = imb_get_anim_type(filename);
440         }
441         
442         return (type && type != ANIM_SEQUENCE);
443 }