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-03-07 23:01:12 +0300
committerPeter Schlaile <peter@schlaile.de>2006-03-07 23:01:12 +0300
commit327d413eb3c0c4cf07b71903eaa27e784be172c3 (patch)
tree9563098700eaa9f038dd476541ba71adf9d50e16 /source/blender/imbuf/intern
parent9ce587e2117dcb2340d75c4bfa2b6e3c1135254c (diff)
this patch features several cleanups and bugfixes for the sequencer:
- blur works again (this was a serious bug in gamwarp...) - seperates all sequence effects into a seperate file with a clean interface - thereby fixing some obscure segfaults - seperates the scope views into a seperate file - adds float support to all effects and scope views - removes a bad level call to open_plugin_seq - FFMPEG seeking improved a lot. - FFMPEG compiles with debian sarge version cleanly - Makes hdaudio seek and resample code really work
Diffstat (limited to 'source/blender/imbuf/intern')
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h1
-rw-r--r--source/blender/imbuf/intern/anim.c160
-rw-r--r--source/blender/imbuf/intern/divers.c33
-rw-r--r--source/blender/imbuf/intern/scaling.c16
-rw-r--r--source/blender/imbuf/intern/util.c28
5 files changed, 147 insertions, 91 deletions
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index 5d597aa5463..602b13df4ca 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -153,6 +153,7 @@ struct anim {
int orientation;
size_t framesize;
int interlacing;
+ int preseek;
/* data */
struct ImBuf * ibuf1, * ibuf2;
diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c
index bd4b268f685..cd238f5013e 100644
--- a/source/blender/imbuf/intern/anim.c
+++ b/source/blender/imbuf/intern/anim.c
@@ -88,12 +88,19 @@
#ifdef WITH_FFMPEG
#include <ffmpeg/avformat.h>
#include <ffmpeg/avcodec.h>
+#include <ffmpeg/rational.h>
+
+/* #define FFMPEG_SEEK_DEBUG 1 */
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
#else
#define FFMPEG_CODEC_IS_POINTER 1
-#define FFMPEG_HAVE_SKIP_FRAME 1
+#define FFMPEG_HAVE_SKIP_OPTS 1
+#endif
+
+#ifndef FF_ER_CAREFUL
+#define FF_ER_CAREFUL FF_ER_CAREFULL
#endif
#endif
@@ -136,6 +143,7 @@ static int startmovie(struct anim * anim) {
anim->framesize = dmImageFrameSize(anim->params);
anim->curposition = 0;
+ anim->preseek = 0;
/*printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
return (0);
@@ -439,6 +447,7 @@ static int startavi (struct anim *anim) {
anim->framesize = anim->x * anim->y * 4;
anim->curposition = 0;
+ anim->preseek = 0;
/* printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
@@ -493,6 +502,18 @@ static ImBuf * avi_fetchibuf (struct anim *anim, int position) {
extern void do_init_ffmpeg();
+#ifdef FFMPEG_CODEC_IS_POINTER
+static AVCodecContext* get_codec_from_stream(AVStream* stream)
+{
+ return stream->codec;
+}
+#else
+static AVCodecContext* get_codec_from_stream(AVStream* stream)
+{
+ return &stream->codec;
+}
+#endif
+
static int startffmpeg(struct anim * anim) {
int i, videoStream;
@@ -519,12 +540,8 @@ static int startffmpeg(struct anim * anim) {
/* 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
- {
+ if(get_codec_from_stream(pFormatCtx->streams[i])->codec_type
+ == CODEC_TYPE_VIDEO) {
videoStream=i;
break;
}
@@ -534,11 +551,7 @@ static int startffmpeg(struct anim * anim) {
return -1;
}
-#ifdef FFMPEG_CODEC_IS_POINTER
- pCodecCtx=pFormatCtx->streams[videoStream]->codec;
-#else
- pCodecCtx=&pFormatCtx->streams[videoStream]->codec;
-#endif
+ pCodecCtx = get_codec_from_stream(pFormatCtx->streams[videoStream]);
/* Find the decoder for the video stream */
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
@@ -551,11 +564,11 @@ static int startffmpeg(struct anim * anim) {
pCodecCtx->workaround_bugs = 1;
pCodecCtx->lowres = 0;
pCodecCtx->idct_algo= FF_IDCT_AUTO;
-#ifdef FFMPEG_HAVE_SKIP_FRAME
+#ifdef FFMPEG_HAVE_SKIP_OPTS
pCodecCtx->skip_frame= AVDISCARD_DEFAULT;
-#endif
pCodecCtx->skip_idct= AVDISCARD_DEFAULT;
pCodecCtx->skip_loop_filter= AVDISCARD_DEFAULT;
+#endif
pCodecCtx->error_resilience= FF_ER_CAREFUL;
pCodecCtx->error_concealment= 3;
@@ -573,7 +586,9 @@ static int startffmpeg(struct anim * anim) {
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;
+ anim->duration = pFormatCtx->duration
+ * av_q2d(pFormatCtx->streams[videoStream]->r_frame_rate)
+ / AV_TIME_BASE;
#endif
anim->params = 0;
@@ -605,7 +620,12 @@ static int startffmpeg(struct anim * anim) {
return -1;
}
- /*printf("x:%d y:%d size:%d interl:%d dur:%d\n", anim->x, anim->y, anim->framesize, anim->interlacing, anim->duration);*/
+ if (pCodecCtx->has_b_frames) {
+ anim->preseek = 18; /* FIXME: detect gopsize ... */
+ } else {
+ anim->preseek = 0;
+ }
+
return (0);
}
@@ -625,22 +645,49 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
PIX_FMT_RGBA32, anim->x, anim->y);
if (position != anim->curposition + 1) {
+ if (position > anim->curposition + 1
+ && anim->preseek
+ && position - (anim->curposition + 1) < anim->preseek) {
+ while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
+ if (packet.stream_index == anim->videoStream) {
+ avcodec_decode_video(
+ anim->pCodecCtx,
+ anim->pFrame, &frameFinished,
+ packet.data, packet.size);
+
+ if (frameFinished) {
+ anim->curposition++;
+ }
+ }
+ av_free_packet(&packet);
+ if (position == anim->curposition+1) {
+ break;
+ }
+ }
+ }
+ }
+
+ 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;
+ double frame_rate =
+ (double) anim->pCodecCtx->frame_rate
+ / (double) anim->pCodecCtx->frame_rate_base;
#else
- long long pos = (long long) position * AV_TIME_BASE
- / av_q2d(anim->pFormatCtx->streams[anim->videoStream]
- ->r_frame_rate);
+ double frame_rate =
+ av_q2d(anim->pFormatCtx->streams[anim->videoStream]
+ ->r_frame_rate);
#endif
+ double time_base =
+ av_q2d(anim->pFormatCtx->streams[anim->videoStream]
+ ->time_base);
+ long long pos = (long long) position * AV_TIME_BASE
+ / frame_rate;
long long st_time = anim->pFormatCtx
->streams[anim->videoStream]->start_time;
+
if (st_time != AV_NOPTS_VALUE) {
- pos += st_time;
+ pos += st_time * AV_TIME_BASE * time_base;
}
av_seek_frame(anim->pFormatCtx, -1,
@@ -653,49 +700,23 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
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 (!keyframe_found) {
+ int scan_pos = position - anim->preseek;
+ if (scan_pos < 0) {
+ scan_pos = 0;
}
- }
- if (max_scan <= 0) {
- fprintf(stderr,
- "Warning: Key frame not found, "
- "doesn't hurt, but _slow_...!\n");
+ pos = (long long) scan_pos * AV_TIME_BASE / frame_rate;
+ if (st_time != AV_NOPTS_VALUE) {
+ pos += st_time * AV_TIME_BASE * time_base;
+ }
}
av_seek_frame(anim->pFormatCtx, -1,
@@ -710,6 +731,11 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
&& !pos_found) {
if (url_ftell(&anim->pFormatCtx->pb) == pos_to_match) {
pos_found = 1;
+ if (anim->pCodecCtx->has_b_frames) {
+ pos_found++;
+ /* account for delay caused by
+ decoding pipeline */
+ }
}
}
if(packet.stream_index == anim->videoStream) {
@@ -717,7 +743,9 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
anim->pFrame, &frameFinished,
packet.data, packet.size);
- if(frameFinished && pos_found) {
+ if (frameFinished && pos_found == 2) {
+ pos_found = 1;
+ } else if(frameFinished && pos_found == 1) {
unsigned char * p =(unsigned char*) ibuf->rect;
unsigned char * e = p + anim->x * anim->y * 4;
@@ -924,3 +952,13 @@ struct ImBuf * IMB_anim_nextpic(struct anim * anim) {
int IMB_anim_get_duration(struct anim *anim) {
return anim->duration;
}
+
+void IMB_anim_set_preseek(struct anim * anim, int preseek)
+{
+ anim->preseek = preseek;
+}
+
+int IMB_anim_get_preseek(struct anim * anim)
+{
+ return anim->preseek;
+}
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 2fc80f6ddcb..c0018d0b336 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -141,25 +141,32 @@ void IMB_interlace(struct ImBuf *ibuf)
void IMB_gamwarp(struct ImBuf *ibuf, double gamma)
{
uchar gam[256];
- int i, do_float=0;
- uchar *rect = (uchar *) ibuf->rect;
- float *rectf = ibuf->rect_float;
+ int i;
+ uchar *rect;
+ float *rectf;
if (ibuf == 0) return;
- if (ibuf->rect == 0) return;
- if (ibuf->rect != NULL) do_float = 1;
if (gamma == 1.0) return;
+ rect = (uchar *) ibuf->rect;
+ rectf = ibuf->rect_float;
+
gamma = 1.0 / gamma;
- for (i = 255 ; i >= 0 ; i--) gam[i] = (255.0 * pow(i / 255.0 ,
- gamma)) + 0.5;
- rect = (uchar *) ibuf->rect;
- for (i = ibuf->x * ibuf->y ; i>0 ; i--, rect+=4){
- rect[0] = gam[rect[0]];
- rect[1] = gam[rect[1]];
- rect[2] = gam[rect[2]];
- if (do_float) {
+ if (rect) {
+ for (i = 255 ; i >= 0 ; i--)
+ gam[i] = (255.0 * pow(i / 255.0 ,
+ gamma)) + 0.5;
+
+ for (i = ibuf->x * ibuf->y ; i>0 ; i--, rect+=4){
+ rect[0] = gam[rect[0]];
+ rect[1] = gam[rect[1]];
+ rect[2] = gam[rect[2]];
+ }
+ }
+
+ if (rectf) {
+ for (i = ibuf->x * ibuf->y ; i>0 ; i--, rectf+=4){
rectf[0] = pow(rectf[0] / 255.0, gamma);
rectf[1] = pow(rectf[1] / 255.0, gamma);
rectf[2] = pow(rectf[2] / 255.0, gamma);
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index c962f1fbde5..8db51f50ee0 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -964,10 +964,18 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, short newx, short newy)
ofsy += stepy;
ofsx = 32768;
- for (x = newx ; x>0 ; x--){
- if (do_rect) *newrect++ = rect[ofsx >> 16];
- if (do_float) *newrectf++ = rectf[ofsx >> 16];
- ofsx += stepx;
+ if (do_rect) {
+ for (x = newx ; x>0 ; x--){
+ *newrect++ = rect[ofsx >> 16];
+ ofsx += stepx;
+ }
+ }
+
+ if (do_float) {
+ for (x = newx ; x>0 ; x--){
+ *newrectf++ = rectf[ofsx >> 16];
+ ofsx += stepx;
+ }
}
}
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index fdb1bed3870..56a03f56ce2 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -217,6 +217,18 @@ void do_init_ffmpeg()
}
}
+#ifdef FFMPEG_CODEC_IS_POINTER
+static AVCodecContext* get_codec_from_stream(AVStream* stream)
+{
+ return stream->codec;
+}
+#else
+static AVCodecContext* get_codec_from_stream(AVStream* stream)
+{
+ return &stream->codec;
+}
+#endif
+
static int isffmpeg (char *filename) {
AVFormatContext *pFormatCtx;
@@ -243,21 +255,14 @@ static int isffmpeg (char *filename) {
/* 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
+ if(get_codec_from_stream(pFormatCtx->streams[i])
+ ->codec_type==CODEC_TYPE_VIDEO)
{
videoStream=i;
break;
}
-#ifdef FFMPEG_CODEC_IS_POINTER
- pCodecCtx=pFormatCtx->streams[videoStream]->codec;
-#else
- pCodecCtx=&pFormatCtx->streams[videoStream]->codec;
-#endif
+ pCodecCtx = get_codec_from_stream(pFormatCtx->streams[videoStream]);
if(videoStream==-1) {
avcodec_close(pCodecCtx);
@@ -274,9 +279,6 @@ static int isffmpeg (char *filename) {
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);