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>2011-11-20 20:08:56 +0400
committerPeter Schlaile <peter@schlaile.de>2011-11-20 20:08:56 +0400
commitaf66321f3b7c1b84fada90fa0ab6f6e0774f4163 (patch)
tree1d5b065e3f913d3386a7268b8bc07e07ba5d2a56 /source/blender/imbuf/intern/anim_movie.c
parent778cd80eb8497c7c2e10385ea9274254ae9494cb (diff)
== Sequencer / FFMPEG ==
This fixed two issues: * RAW DV-seeking has to be done using DTS. Sounds silly, but ffmpeg tracks internal state in RAW DV format decoder and runs mad, if we seek by byte. Don't know, why I haven't noticed that, when I added it. * real fix(tm) for #29295 problem was: we did AVFrame read ahead, and the pattern read_frame -> decode -> read_frame -> do color conversion of first frame works everywhere but RAW RGB-files which do some pointer shuffling within ffmpeg to save a memcpy... I removed read ahead completely, since it didn't work like originally intented. Might come back later, but the original purpose (making resyncing easier if we are completely lost in stream) it never fullfilled.
Diffstat (limited to 'source/blender/imbuf/intern/anim_movie.c')
-rw-r--r--source/blender/imbuf/intern/anim_movie.c109
1 files changed, 45 insertions, 64 deletions
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index db27c1cee63..642b84f4897 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -504,7 +504,6 @@ static int startffmpeg(struct anim * anim) {
anim->last_frame = 0;
anim->last_pts = -1;
anim->next_pts = -1;
- anim->next_undecoded_pts = -1;
anim->next_packet.stream_index = -1;
anim->pFormatCtx = pFormatCtx;
@@ -513,6 +512,7 @@ static int startffmpeg(struct anim * anim) {
anim->videoStream = videoStream;
anim->pFrame = avcodec_alloc_frame();
+ anim->pFrameComplete = FALSE;
anim->pFrameDeinterlaced = avcodec_alloc_frame();
anim->pFrameRGB = avcodec_alloc_frame();
@@ -602,6 +602,10 @@ static void ffmpeg_postprocess(struct anim * anim)
ibuf->profile = IB_PROFILE_SRGB;
+ if (!anim->pFrameComplete) {
+ return;
+ }
+
/* This means the data wasnt read properly,
this check stops crashing */
if (input->data[0]==0 && input->data[1]==0
@@ -611,6 +615,12 @@ static void ffmpeg_postprocess(struct anim * anim)
return;
}
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG,
+ " POSTPROC: anim->pFrame planes: %p %p %p %p\n",
+ input->data[0], input->data[1], input->data[2],
+ input->data[3]);
+
+
if (anim->ib_flags & IB_animdeinterlace) {
if (avpicture_deinterlace(
(AVPicture*)
@@ -715,42 +725,15 @@ static void ffmpeg_postprocess(struct anim * anim)
}
}
-/* decode one video frame and load the next packet into anim->packet,
- so that we can obtain next_pts and next undecoded pts */
+/* decode one video frame also considering the packet read into next_packet */
static int ffmpeg_decode_video_frame(struct anim * anim)
{
- int frameFinished = 0;
int rval = 0;
av_log(anim->pFormatCtx, AV_LOG_DEBUG, " DECODE VIDEO FRAME\n");
- anim->next_undecoded_pts = -1;
-
if (anim->next_packet.stream_index == anim->videoStream) {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- " DECODE: cached next packet\n");
-
- avcodec_decode_video2(anim->pCodecCtx,
- anim->pFrame, &frameFinished,
- &anim->next_packet);
-
- if (frameFinished) {
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG,
- " FRAME DONE: "
- "next_pts=%lld pkt_pts=%lld\n",
- (anim->pFrame->pts == AV_NOPTS_VALUE) ?
- -1 : (long long int)anim->pFrame->pts,
- (anim->pFrame->pkt_pts == AV_NOPTS_VALUE) ?
- -1 : (long long int)anim->pFrame->pkt_pts);
- anim->next_pts =
- av_get_pts_from_frame(anim->pFormatCtx,
- anim->pFrame);
-
- ffmpeg_postprocess(anim);
- }
-
av_free_packet(&anim->next_packet);
anim->next_packet.stream_index = -1;
}
@@ -771,21 +754,14 @@ static int ffmpeg_decode_video_frame(struct anim * anim)
(anim->next_packet.flags & AV_PKT_FLAG_KEY) ?
" KEY" : "");
if (anim->next_packet.stream_index == anim->videoStream) {
- if (frameFinished) {
- av_log(anim->pFormatCtx,
- AV_LOG_DEBUG,
- " FRAME finished, we leave\n");
- anim->next_undecoded_pts
- = anim->next_packet.dts;
- break;
- }
+ anim->pFrameComplete = 0;
avcodec_decode_video2(
anim->pCodecCtx,
- anim->pFrame, &frameFinished,
+ anim->pFrame, &anim->pFrameComplete,
&anim->next_packet);
- if (frameFinished) {
+ if (anim->pFrameComplete) {
anim->next_pts = av_get_pts_from_frame(
anim->pFormatCtx, anim->pFrame);
@@ -799,15 +775,16 @@ static int ffmpeg_decode_video_frame(struct anim * anim)
== AV_NOPTS_VALUE) ?
-1 : (long long int)anim->pFrame->pkt_pts,
(long long int)anim->next_pts);
-
- ffmpeg_postprocess(anim);
}
+ break;
}
av_free_packet(&anim->next_packet);
anim->next_packet.stream_index = -1;
}
if (rval < 0) {
+ anim->next_packet.stream_index = -1;
+
av_log(anim->pFormatCtx,
AV_LOG_ERROR, " DECODE READ FAILED: av_read_frame() "
"returned error: %d\n", rval);
@@ -875,7 +852,7 @@ static int match_format(const char *name, AVFormatContext * pFormatCtx)
static int ffmpeg_seek_by_byte(AVFormatContext *pFormatCtx)
{
- static const char * byte_seek_list [] = { "dv", "mpegts", 0 };
+ static const char * byte_seek_list [] = { "mpegts", 0 };
const char ** p;
if (pFormatCtx->iformat->flags & AVFMT_TS_DISCONT) {
@@ -928,7 +905,8 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
tc_index, new_frame_index);
} else {
pts_to_search = (long long)
- floor(((double) position) / pts_time_base / frame_rate + 0.5);
+ floor(((double) position)
+ / pts_time_base / frame_rate + 0.5);
if (st_time != AV_NOPTS_VALUE) {
pts_to_search += st_time / pts_time_base
@@ -939,36 +917,23 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
av_log(anim->pFormatCtx, AV_LOG_DEBUG,
"FETCH: looking for PTS=%lld "
"(pts_timebase=%g, frame_rate=%g, st_time=%lld)\n",
- (long long int)pts_to_search, pts_time_base, frame_rate, st_time);
+ (long long int)pts_to_search,pts_time_base, frame_rate, st_time);
if (anim->last_frame &&
anim->last_pts <= pts_to_search && anim->next_pts > pts_to_search){
av_log(anim->pFormatCtx, AV_LOG_DEBUG,
"FETCH: frame repeat: last: %lld next: %lld\n",
- (long long int)anim->last_pts, (long long int)anim->next_pts);
+ (long long int)anim->last_pts,
+ (long long int)anim->next_pts);
IMB_refImBuf(anim->last_frame);
anim->curposition = position;
return anim->last_frame;
}
- IMB_freeImBuf(anim->last_frame);
- anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
-
- if (anim->next_pts <= pts_to_search &&
- anim->next_undecoded_pts > pts_to_search) {
- av_log(anim->pFormatCtx, AV_LOG_DEBUG,
- "FETCH: no seek necessary: "
- "next: %lld next undecoded: %lld\n",
- (long long int)anim->next_pts,
- (long long int)anim->next_undecoded_pts);
-
- /* we are already done :) */
-
- } else if (position > anim->curposition + 1
- && anim->preseek
- && !tc_index
- && position - (anim->curposition + 1) < anim->preseek) {
-
+ if (position > anim->curposition + 1
+ && anim->preseek
+ && !tc_index
+ && position - (anim->curposition + 1) < anim->preseek) {
av_log(anim->pFormatCtx, AV_LOG_DEBUG,
"FETCH: within preseek interval (no index)\n");
@@ -1017,6 +982,11 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
} else {
pos = (long long) (position - anim->preseek)
* AV_TIME_BASE / frame_rate;
+
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG,
+ "NO INDEX seek pos = %lld, st_time = %lld\n",
+ pos, (st_time != AV_NOPTS_VALUE) ? st_time : 0);
+
if (pos < 0) {
pos = 0;
}
@@ -1025,6 +995,9 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
pos += st_time;
}
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG,
+ "NO INDEX final seek pos = %lld\n", pos);
+
ret = av_seek_frame(anim->pFormatCtx, -1,
pos, AVSEEK_FLAG_BACKWARD);
}
@@ -1054,8 +1027,16 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
} else if (position == 0 && anim->curposition == -1) {
/* first frame without seeking special case... */
ffmpeg_decode_video_frame(anim);
+ } else {
+ av_log(anim->pFormatCtx, AV_LOG_DEBUG,
+ "FETCH: no seek necessary, just continue...\n");
}
+ IMB_freeImBuf(anim->last_frame);
+ anim->last_frame = IMB_allocImBuf(anim->x, anim->y, 32, IB_rect);
+
+ ffmpeg_postprocess(anim);
+
anim->last_pts = anim->next_pts;
ffmpeg_decode_video_frame(anim);
@@ -1063,7 +1044,7 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position,
anim->curposition = position;
IMB_refImBuf(anim->last_frame);
-
+
return anim->last_frame;
}