Simplified the code a bit, removed debugging output and

added a work-around for the problem that FindKeyFrameForFrame()
may return another frame for a previously found keyframe
(due to rounding issues in the extrator).

At the moment, files which used to play horribly play pretty well
now for me. One remaining problem is that audio may be mute when
seeking far ahead in file, and the audio decoding has to catch
up. It will eventually be all ok. Once a section of the file has
played, it becomes seekable. This seems to be weird behavior of
some FFmpeg demuxers, and only with some files.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38507 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2010-09-01 21:55:11 +00:00
parent 2cc22e8a26
commit 41af979eb8

View File

@ -117,9 +117,8 @@ MediaTrackVideoSupplier::ReadFrame(void* buffer, bigtime_t* performanceTime,
fprintf(stderr, "MediaTrackVideoSupplier::ReadFrame() - "
"error while reading frame of track: %s\n", strerror(ret));
}
} else {
} else
fPerformanceTime = mediaHeader.start_time;
}
fCurrentFrame = fVideoTrack->CurrentFrame();
if (performanceTime)
@ -148,8 +147,11 @@ MediaTrackVideoSupplier::FindKeyFrameForFrame(int64* frame)
if (!fVideoTrack)
return B_NO_INIT;
return fVideoTrack->FindKeyFrameForFrame(frame,
//int64 wantedFrame = *frame;
status_t ret = fVideoTrack->FindKeyFrameForFrame(frame,
B_MEDIA_SEEK_CLOSEST_BACKWARD);
//printf("found keyframe for frame %lld -> %lld\n", wantedFrame, *frame);
return ret;
}
@ -184,31 +186,47 @@ MediaTrackVideoSupplier::SeekToFrame(int64* frame)
return B_NO_INIT;
int64 wantFrame = *frame;
int64 currentFrame = fVideoTrack->CurrentFrame();
if (wantFrame == currentFrame)
if (wantFrame == fCurrentFrame)
return B_OK;
status_t ret = fVideoTrack->FindKeyFrameForFrame(frame,
B_MEDIA_SEEK_CLOSEST_BACKWARD);
if (ret < B_OK)
if (ret != B_OK)
return ret;
if (wantFrame > *frame) {
// Work around a rounding problem with some extractors and
// converting frames <-> time <-> internal time.
int64 nextWantFrame = wantFrame + 1;
if (fVideoTrack->FindKeyFrameForFrame(&nextWantFrame,
B_MEDIA_SEEK_CLOSEST_BACKWARD) == B_OK) {
if (nextWantFrame == wantFrame)
*frame = wantFrame + 1;
}
}
if (*frame < currentFrame && wantFrame > currentFrame) {
*frame = currentFrame;
//if (wantFrame != *frame) {
// printf("keyframe for frame: %lld -> %lld\n", wantFrame, *frame);
//}
if (*frame <= fCurrentFrame && wantFrame > fCurrentFrame) {
// The current frame is already closer to the wanted frame
// than the next keyframe before it.
*frame = fCurrentFrame;
return B_OK;
}
if (wantFrame != *frame) {
printf("seeked by frame: %lld -> %lld, was %lld\n", wantFrame, *frame,
currentFrame);
}
ret = fVideoTrack->SeekToFrame(frame);
if (ret == B_OK) {
fCurrentFrame = *frame;
fPerformanceTime = fVideoTrack->CurrentTime();
}
if (ret != B_OK)
return ret;
//if (wantFrame != *frame) {
// printf("seeked by frame: %lld -> %lld, was %lld\n", wantFrame, *frame,
// fCurrentFrame);
//}
fCurrentFrame = *frame;
fPerformanceTime = fVideoTrack->CurrentTime();
return ret;
}