Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2006-02-05 22:23:34 +0300
committerPeter Schlaile <peter@schlaile.de>2006-02-05 22:23:34 +0300
commit334b05741f0ed51f192c17328b62c7540970d1bf (patch)
treed6c80eef057a39f567f5aff3c91fdc67a8e5abda /source/blender/imbuf/intern
parent38c4a3a209aa920d2d851c4250425bbfd66b508b (diff)
* Add memcache limitor-support to imbufs
* Add ffmpeg-read support in anim.c and util.c * Makes ImBufs refcountable. You can now increase an internal refcounter in ImBufs (using IMB_refImBuf) which is decreased by freeImBuf. This makes it possible to simply pass ImBuf pointers around in the sequencer saving a few memcopies.
Diffstat (limited to 'source/blender/imbuf/intern')
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h16
-rw-r--r--source/blender/imbuf/intern/Makefile5
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c108
-rw-r--r--source/blender/imbuf/intern/anim.c311
-rw-r--r--source/blender/imbuf/intern/cmap.c2
-rw-r--r--source/blender/imbuf/intern/util.c104
6 files changed, 536 insertions, 10 deletions
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index 77958f82e42..5d597aa5463 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -78,6 +78,11 @@
#endif /* _WIN32 || __APPLE__ */
#endif /* WITH_QUICKTIME */
+#ifdef WITH_FFMPEG
+#include <ffmpeg/avformat.h>
+#include <ffmpeg/avcodec.h>
+#endif
+
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -112,6 +117,7 @@
#define ANIM_MDEC (1 << 5)
#define ANIM_AVI (1 << 6)
#define ANIM_QTIME (1 << 7)
+#define ANIM_FFMPEG (1 << 8)
#define ANIM5_MMAP 0
#define ANIM5_MALLOC 1
@@ -168,6 +174,16 @@ struct anim {
/* quicktime */
struct _QuicktimeMovie *qtime;
#endif /* WITH_QUICKTIME */
+
+#ifdef WITH_FFMPEG
+ AVFormatContext *pFormatCtx;
+ AVCodecContext *pCodecCtx;
+ AVCodec *pCodec;
+ AVFrame *pFrameRGB;
+ AVFrame *pFrame;
+ int videoStream;
+#endif
+
};
#endif
diff --git a/source/blender/imbuf/intern/Makefile b/source/blender/imbuf/intern/Makefile
index 6f8fc7d31bb..4efba0cd988 100644
--- a/source/blender/imbuf/intern/Makefile
+++ b/source/blender/imbuf/intern/Makefile
@@ -62,6 +62,7 @@ CPPFLAGS += -I../../avi
CPPFLAGS += -I../../quicktime
# path to the guarded memory allocator
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I$(NAN_MEMUTIL)/include
# This is not really needed, but until /include is cleaned, it must be
# there for proper compilation.
# - No, it is also needed in antialias, for listbase (nzc)
@@ -73,3 +74,7 @@ ifeq ($(WITH_QUICKTIME), true)
CPPFLAGS += -DWITH_QUICKTIME
endif
+ifeq ($(WITH_FFMPEG), true)
+ CPPFLAGS += -DWITH_FFMPEG
+endif
+
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 0c1d182f4b2..89873b92f3d 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -43,6 +43,7 @@
#include "IMB_divers.h"
#include "IMB_allocimbuf.h"
+#include "MEM_CacheLimiterC-Api.h"
static unsigned int dfltcmap[16] = {
0x00000000, 0xffffffff, 0x777777ff, 0xccccccff,
@@ -135,17 +136,27 @@ void IMB_freecmapImBuf(struct ImBuf * ibuf)
void IMB_freeImBuf(struct ImBuf * ibuf)
{
if (ibuf){
- imb_freeplanesImBuf(ibuf);
- imb_freerectImBuf(ibuf);
- imb_freerectfloatImBuf(ibuf);
- IMB_freezbufImBuf(ibuf);
- IMB_freezbuffloatImBuf(ibuf);
- IMB_freecmapImBuf(ibuf);
- freeencodedbufferImBuf(ibuf);
- MEM_freeN(ibuf);
+ if (ibuf->refcounter > 0) {
+ ibuf->refcounter--;
+ } else {
+ imb_freeplanesImBuf(ibuf);
+ imb_freerectImBuf(ibuf);
+ imb_freerectfloatImBuf(ibuf);
+ IMB_freezbufImBuf(ibuf);
+ IMB_freezbuffloatImBuf(ibuf);
+ IMB_freecmapImBuf(ibuf);
+ freeencodedbufferImBuf(ibuf);
+ IMB_cache_limiter_unmanage(ibuf);
+ MEM_freeN(ibuf);
+ }
}
}
+void IMB_refImBuf(struct ImBuf * ibuf)
+{
+ ibuf->refcounter++;
+}
+
short addzbufImBuf(struct ImBuf * ibuf)
{
int size;
@@ -444,7 +455,8 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
// set malloc flag
tbuf.mall = ibuf2->mall;
-
+ tbuf.c_handle = 0;
+
*ibuf2 = tbuf;
if (ibuf1->cmap){
@@ -454,3 +466,81 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
return(ibuf2);
}
+
+/* support for cache limiting */
+
+static void imbuf_cache_destructor(void * data)
+{
+ struct ImBuf * ibuf = (struct ImBuf*) data;
+
+ imb_freeplanesImBuf(ibuf);
+ imb_freerectImBuf(ibuf);
+ IMB_freezbufImBuf(ibuf);
+ IMB_freecmapImBuf(ibuf);
+ freeencodedbufferImBuf(ibuf);
+
+ ibuf->c_handle = 0;
+}
+
+static MEM_CacheLimiterC ** get_imbuf_cache_limiter()
+{
+ static MEM_CacheLimiterC * c = 0;
+ if (!c) {
+ c = new_MEM_CacheLimiter(imbuf_cache_destructor);
+ }
+ return &c;
+}
+
+void IMB_free_cache_limiter()
+{
+ delete_MEM_CacheLimiter(*get_imbuf_cache_limiter());
+ *get_imbuf_cache_limiter() = 0;
+}
+
+void IMB_cache_limiter_insert(struct ImBuf * i)
+{
+ if (!i->c_handle) {
+ i->c_handle = MEM_CacheLimiter_insert(
+ *get_imbuf_cache_limiter(), i);
+ MEM_CacheLimiter_ref(i->c_handle);
+ MEM_CacheLimiter_enforce_limits(
+ *get_imbuf_cache_limiter());
+ MEM_CacheLimiter_unref(i->c_handle);
+ }
+}
+
+void IMB_cache_limiter_unmanage(struct ImBuf * i)
+{
+ if (i->c_handle) {
+ MEM_CacheLimiter_unmanage(i->c_handle);
+ i->c_handle = 0;
+ }
+}
+
+void IMB_cache_limiter_touch(struct ImBuf * i)
+{
+ if (i->c_handle) {
+ MEM_CacheLimiter_touch(i->c_handle);
+ }
+}
+
+void IMB_cache_limiter_ref(struct ImBuf * i)
+{
+ if (i->c_handle) {
+ MEM_CacheLimiter_ref(i->c_handle);
+ }
+}
+
+void IMB_cache_limiter_unref(struct ImBuf * i)
+{
+ if (i->c_handle) {
+ MEM_CacheLimiter_unref(i->c_handle);
+ }
+}
+
+int IMB_cache_limiter_get_refcount(struct ImBuf * i)
+{
+ if (i->c_handle) {
+ MEM_CacheLimiter_get_refcount(i->c_handle);
+ }
+}
diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c
index 51fadc5c06a..ad563cc3bb2 100644
--- a/source/blender/imbuf/intern/anim.c
+++ b/source/blender/imbuf/intern/anim.c
@@ -85,6 +85,17 @@
#include "IMB_anim.h"
#include "IMB_anim5.h"
+#ifdef WITH_FFMPEG
+#include <ffmpeg/avformat.h>
+#include <ffmpeg/avcodec.h>
+
+#if LIBAVFORMAT_VERSION_INT < (49 << 16)
+#define FFMPEG_OLD_FRAME_RATE 1
+#else
+#define FFMPEG_CODEC_IS_POINTER 1
+#endif
+
+#endif
/****/
@@ -293,6 +304,7 @@ void IMB_free_anim_ibuf(struct anim * anim) {
anim->ibuf1 = anim->ibuf2 = NULL;
}
+static void free_anim_ffmpeg(struct anim * anim);
void IMB_free_anim(struct anim * anim) {
if (anim == NULL) {
@@ -308,6 +320,9 @@ void IMB_free_anim(struct anim * anim) {
#ifdef WITH_QUICKTIME
free_anim_quicktime(anim);
#endif
+#ifdef WITH_FFMPEG
+ free_anim_ffmpeg(anim);
+#endif
free(anim);
}
@@ -473,6 +488,287 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) {
return ibuf;
}
+#ifdef WITH_FFMPEG
+
+extern void do_init_ffmpeg();
+
+static int startffmpeg(struct anim * anim) {
+ int i, videoStream;
+
+ AVCodec *pCodec;
+ AVFormatContext *pFormatCtx;
+ AVCodecContext *pCodecCtx;
+
+ if (anim == 0) return(-1);
+
+ do_init_ffmpeg();
+
+ if(av_open_input_file(&pFormatCtx, anim->name, NULL, 0, NULL)!=0) {
+ return -1;
+ }
+
+ if(av_find_stream_info(pFormatCtx)<0) {
+ av_close_input_file(pFormatCtx);
+ return -1;
+ }
+
+ dump_format(pFormatCtx, 0, anim->name, 0);
+
+
+ /* Find the first video stream */
+ videoStream=-1;
+ for(i=0; i<pFormatCtx->nb_streams; i++)
+#ifdef FFMPEG_CODEC_IS_POINTER
+ if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
+#else
+ if(pFormatCtx->streams[i]->codec.codec_type==CODEC_TYPE_VIDEO)
+#endif
+ {
+ videoStream=i;
+ break;
+ }
+
+ if(videoStream==-1) {
+ av_close_input_file(pFormatCtx);
+ return -1;
+ }
+
+#ifdef FFMPEG_CODEC_IS_POINTER
+ pCodecCtx=pFormatCtx->streams[videoStream]->codec;
+#else
+ pCodecCtx=&pFormatCtx->streams[videoStream]->codec;
+#endif
+
+ /* Find the decoder for the video stream */
+ pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
+ if(pCodec==NULL) {
+ avcodec_close(pCodecCtx);
+ av_close_input_file(pFormatCtx);
+ return -1;
+ }
+
+ pCodecCtx->workaround_bugs = 1;
+ pCodecCtx->lowres = 0;
+ pCodecCtx->idct_algo= FF_IDCT_AUTO;
+ pCodecCtx->skip_frame= AVDISCARD_DEFAULT;
+ pCodecCtx->skip_idct= AVDISCARD_DEFAULT;
+ pCodecCtx->skip_loop_filter= AVDISCARD_DEFAULT;
+ pCodecCtx->error_resilience= FF_ER_CAREFUL;
+ pCodecCtx->error_concealment= 3;
+
+ if(avcodec_open(pCodecCtx, pCodec)<0) {
+ avcodec_close(pCodecCtx);
+ av_close_input_file(pFormatCtx);
+ return -1;
+ }
+
+#ifdef FFMPEG_OLD_FRAME_RATE
+ if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)
+ pCodecCtx->frame_rate_base=1000;
+
+
+ anim->duration = pFormatCtx->duration * pCodecCtx->frame_rate
+ / pCodecCtx->frame_rate_base / AV_TIME_BASE;
+#else
+ anim->duration = pFormatCtx->duration * av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate) / AV_TIME_BASE;
+
+#endif
+ anim->params = 0;
+
+ anim->x = pCodecCtx->width;
+ anim->y = pCodecCtx->height;
+ anim->interlacing = 0;
+ anim->orientation = 0;
+ anim->framesize = anim->x * anim->y * 4;
+
+ anim->curposition = -1;
+
+ anim->pFormatCtx = pFormatCtx;
+ anim->pCodecCtx = pCodecCtx;
+ anim->pCodec = pCodec;
+ anim->videoStream = videoStream;
+
+ anim->pFrame = avcodec_alloc_frame();
+ anim->pFrameRGB = avcodec_alloc_frame();
+
+ if (avpicture_get_size(PIX_FMT_RGBA32, anim->x, anim->y)
+ != anim->x * anim->y * 4) {
+ fprintf (stderr,
+ "ffmpeg has changed alloc scheme ... ARGHHH!\n");
+ avcodec_close(anim->pCodecCtx);
+ av_close_input_file(anim->pFormatCtx);
+ av_free(anim->pFrameRGB);
+ av_free(anim->pFrame);
+ return -1;
+ }
+
+ /*printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
+ return (0);
+}
+
+static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
+ ImBuf * ibuf;
+ int frameFinished;
+ AVPacket packet;
+ offset_t pos_to_match = AV_NOPTS_VALUE;
+ int pos_found = 1;
+
+ if (anim == 0) return (0);
+
+ ibuf = IMB_allocImBuf(anim->x, anim->y, 24, IB_rect, 0);
+
+ avpicture_fill((AVPicture *)anim->pFrameRGB,
+ (unsigned char*) ibuf->rect,
+ PIX_FMT_RGBA32, anim->x, anim->y);
+
+ if (position != anim->curposition + 1) {
+ int keyframe_found = 0;
+ int scan_pos = position;
+ int max_scan = 18; /* max mpeg 1/2 gop size */
+#ifdef FFMPEG_OLD_FRAME_RATE
+ long long pos = (long long) anim->pCodecCtx->frame_rate_base
+ * position * AV_TIME_BASE
+ / anim->pCodecCtx->frame_rate;
+#else
+ long long pos = (long long) position * AV_TIME_BASE
+ / av_q2d(anim->pFormatCtx->streams[anim->videoStream]
+ ->r_frame_rate);
+#endif
+ long long st_time = anim->pFormatCtx
+ ->streams[anim->videoStream]->start_time;
+ if (st_time != AV_NOPTS_VALUE) {
+ pos += st_time;
+ }
+
+ av_seek_frame(anim->pFormatCtx, -1,
+ pos, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD );
+
+ while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
+ if(packet.stream_index == anim->videoStream) {
+ pos_to_match
+ = url_ftell(&anim->pFormatCtx->pb);
+ if ((packet.flags & PKT_FLAG_KEY) != 0) {
+ keyframe_found = 1;
+ }
+ av_free_packet(&packet);
+ break;
+ }
+ av_free_packet(&packet);
+ }
+ /* if all ffmpeg seek bugs are fixed, the following
+ loop is obsolete ... (but does not hurt very much...)
+ */
+
+ while (!keyframe_found && max_scan--) {
+ scan_pos--;
+#ifdef FFMPEG_OLD_FRAME_RATE
+ pos = (long long)
+ anim->pCodecCtx->frame_rate_base
+ * scan_pos * AV_TIME_BASE
+ / anim->pCodecCtx->frame_rate;
+#else
+ pos = (long long) scan_pos * AV_TIME_BASE
+ / av_q2d(anim->pFormatCtx
+ ->streams[anim->videoStream]
+ ->r_frame_rate);
+#endif
+ av_seek_frame(anim->pFormatCtx, -1,
+ pos,
+ AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
+
+ while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
+ if(packet.stream_index == anim->videoStream) {
+ if ((packet.flags & PKT_FLAG_KEY)
+ != 0) {
+ keyframe_found = 1;
+ }
+ av_free_packet(&packet);
+ break;
+ }
+ av_free_packet(&packet);
+ }
+ }
+
+ if (max_scan <= 0) {
+ fprintf(stderr,
+ "Warning: Key frame not found, "
+ "doesn't hurt, but _slow_...!\n");
+ }
+
+ av_seek_frame(anim->pFormatCtx, -1,
+ pos, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
+
+ pos_found = 0;
+ avcodec_flush_buffers(anim->pCodecCtx);
+ }
+
+ while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
+ if (packet.stream_index == anim->videoStream
+ && !pos_found) {
+ if (url_ftell(&anim->pFormatCtx->pb) == pos_to_match) {
+ pos_found = 1;
+ }
+ }
+ if(packet.stream_index == anim->videoStream) {
+ avcodec_decode_video(anim->pCodecCtx,
+ anim->pFrame, &frameFinished,
+ packet.data, packet.size);
+
+ if(frameFinished && pos_found) {
+ unsigned char * p =(unsigned char*) ibuf->rect;
+ unsigned char * e = p + anim->x * anim->y * 4;
+
+ img_convert((AVPicture *)anim->pFrameRGB,
+ PIX_FMT_RGBA32,
+ (AVPicture*)anim->pFrame,
+ anim->pCodecCtx->pix_fmt,
+ anim->pCodecCtx->width,
+ anim->pCodecCtx->height);
+ IMB_flipy(ibuf);
+ if (G.order == L_ENDIAN) {
+ /* BGRA -> RGBA */
+ while (p != e) {
+ unsigned char a = p[0];
+ p[0] = p[2];
+ p[2] = a;
+ p += 4;
+ }
+ } else {
+ /* ARGB -> RGBA */
+ while (p != e) {
+ unsigned long a =
+ *(unsigned long*) p;
+ a = (a << 8) | p[0];
+ *(unsigned long*) p = a;
+ p += 4;
+ }
+ }
+ av_free_packet(&packet);
+ break;
+ }
+ }
+
+ av_free_packet(&packet);
+ }
+
+ return(ibuf);
+}
+
+static void free_anim_ffmpeg(struct anim * anim) {
+ if (anim == NULL) return;
+
+ if (anim->pCodecCtx) {
+ avcodec_close(anim->pCodecCtx);
+ av_close_input_file(anim->pFormatCtx);
+ av_free(anim->pFrameRGB);
+ av_free(anim->pFrame);
+ }
+ anim->duration = 0;
+}
+
+#endif
+
+
/* probeer volgende plaatje te lezen */
/* Geen plaatje, probeer dan volgende animatie te openen */
/* gelukt, haal dan eerste plaatje van animatie */
@@ -488,6 +784,9 @@ static struct ImBuf * anim_getnew(struct anim * anim) {
#ifdef WITH_QUICKTIME
free_anim_quicktime(anim);
#endif
+#ifdef WITH_FFMPEG
+ free_anim_ffmpeg(anim);
+#endif
if (anim->curtype != 0) return (0);
anim->curtype = imb_get_anim_type(anim->name);
@@ -521,6 +820,12 @@ static struct ImBuf * anim_getnew(struct anim * anim) {
ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0);
break;
#endif
+#ifdef WITH_FFMPEG
+ case ANIM_FFMPEG:
+ if (startffmpeg(anim)) return (0);
+ ibuf = IMB_allocImBuf (anim->x, anim->y, 24, 0, 0);
+ break;
+#endif
}
return(ibuf);
@@ -585,6 +890,12 @@ struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
if (ibuf) anim->curposition = position;
break;
#endif
+#ifdef WITH_FFMPEG
+ case ANIM_FFMPEG:
+ ibuf = ffmpeg_fetchibuf(anim, position);
+ if (ibuf) anim->curposition = position;
+ break;
+#endif
}
if (ibuf) {
diff --git a/source/blender/imbuf/intern/cmap.c b/source/blender/imbuf/intern/cmap.c
index c955fbf7e60..7b4962d8837 100644
--- a/source/blender/imbuf/intern/cmap.c
+++ b/source/blender/imbuf/intern/cmap.c
@@ -49,6 +49,7 @@ static short lastmincol;
static short lastcbits;
short alpha_col0 = FALSE;
+extern void IMB_free_cache_limiter();
/*
* there still is a bug here. If you want to convert an image to a 1 bit colormap you get
@@ -61,6 +62,7 @@ void IMB_freeImBufdata(void)
lastcube= 0;
if (lastcoltab) free(lastcoltab);
lastcoltab= 0;
+ IMB_free_cache_limiter();
}
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 8110a115471..fdb1bed3870 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -58,6 +58,18 @@
#include "quicktime_import.h"
#endif
+#ifdef WITH_FFMPEG
+#include <ffmpeg/avcodec.h>
+#include <ffmpeg/avformat.h>
+
+#if LIBAVFORMAT_VERSION_INT < (49 << 16)
+#define FFMPEG_OLD_FRAME_RATE 1
+#else
+#define FFMPEG_CODEC_IS_POINTER 1
+#endif
+
+#endif
+
#define UTIL_DEBUG 0
/* from misc_util: flip the bytes from x */
@@ -195,15 +207,103 @@ static int isqtime (char *name) {
}
#endif
+#ifdef WITH_FFMPEG
+void do_init_ffmpeg()
+{
+ static int ffmpeg_init = 0;
+ if (!ffmpeg_init) {
+ ffmpeg_init = 1;
+ av_register_all();
+ }
+}
+
+
+static int isffmpeg (char *filename) {
+ AVFormatContext *pFormatCtx;
+ int i, videoStream;
+ AVCodec *pCodec;
+ AVCodecContext *pCodecCtx;
+
+ do_init_ffmpeg();
+
+ if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0) {
+ fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
+ return 0;
+ }
+
+ if(av_find_stream_info(pFormatCtx)<0) {
+ fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
+ av_close_input_file(pFormatCtx);
+ return 0;
+ }
+
+ dump_format(pFormatCtx, 0, filename, 0);
+
+
+ /* Find the first video stream */
+ videoStream=-1;
+ for(i=0; i<pFormatCtx->nb_streams; i++)
+#ifdef FFMPEG_CODEC_IS_POINTER
+ if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
+#else
+ if(pFormatCtx->streams[i]->codec.codec_type==CODEC_TYPE_VIDEO)
+#endif
+ {
+ videoStream=i;
+ break;
+ }
+
+#ifdef FFMPEG_CODEC_IS_POINTER
+ pCodecCtx=pFormatCtx->streams[videoStream]->codec;
+#else
+ pCodecCtx=&pFormatCtx->streams[videoStream]->codec;
+#endif
+
+ if(videoStream==-1) {
+ avcodec_close(pCodecCtx);
+ av_close_input_file(pFormatCtx);
+ return 0;
+ }
+
+
+ /* Find the decoder for the video stream */
+ pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
+ if(pCodec==NULL) {
+ avcodec_close(pCodecCtx);
+ av_close_input_file(pFormatCtx);
+ return 0;
+ }
+
+ if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
+ pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
+
+ if(avcodec_open(pCodecCtx, pCodec)<0) {
+ avcodec_close(pCodecCtx);
+ av_close_input_file(pFormatCtx);
+ return 0;
+ }
+
+ avcodec_close(pCodecCtx);
+ av_close_input_file(pFormatCtx);
+
+ return 1;
+}
+#endif
+
int imb_get_anim_type(char * name) {
int type;
struct stat st;
if(UTIL_DEBUG) printf("in getanimtype: %s\n", name);
+#ifdef WITH_FFMPEG
+ /* stat test below fails on large files > 4GB */
+ if (isffmpeg(name)) return (ANIM_FFMPEG);
+#endif
+
if (ib_stat(name,&st) == -1) return(0);
if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
-
+
if (isavi(name)) return (ANIM_AVI);
if (ismovie(name)) return (ANIM_MOVIE);
@@ -223,6 +323,7 @@ int IMB_isanim(char *filename) {
if (G.have_quicktime){
if( BLI_testextensie(filename, ".avi")
|| BLI_testextensie(filename, ".flc")
+ || BLI_testextensie(filename, ".dv")
|| BLI_testextensie(filename, ".mov")
|| BLI_testextensie(filename, ".movie")
|| BLI_testextensie(filename, ".mv")) {
@@ -232,6 +333,7 @@ int IMB_isanim(char *filename) {
}
} else { // no quicktime
if( BLI_testextensie(filename, ".avi")
+ || BLI_testextensie(filename, ".dv")
|| BLI_testextensie(filename, ".mv")) {
type = imb_get_anim_type(filename);
}