Might have implemented seeking to keyframes (video streams only for now), but
I need to test it yet... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24498 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (c) 2008, Stephan Aßmus <[email protected]>
|
||||||
* Copyright (c) 2007, Marcus Overhagen
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@@ -249,8 +250,8 @@ StandardIndex::Seek(int stream_index, uint32 seekTo, int64 *frame,
|
|||||||
} else
|
} else
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// TODO: Actually take keyframe flags into account!
|
|
||||||
if (stream->is_audio) {
|
if (stream->is_audio) {
|
||||||
|
// TODO: Actually take keyframe flags into account!
|
||||||
int64 bytes = 0;
|
int64 bytes = 0;
|
||||||
for (uint32 i = 0; i < fIndexSize; i++) {
|
for (uint32 i = 0; i < fIndexSize; i++) {
|
||||||
if ((fIndex[i].chunk_id & 0xffff) == data->chunk_id) {
|
if ((fIndex[i].chunk_id & 0xffff) == data->chunk_id) {
|
||||||
@@ -264,16 +265,52 @@ StandardIndex::Seek(int stream_index, uint32 seekTo, int64 *frame,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (stream->is_video) {
|
} else if (stream->is_video) {
|
||||||
|
// iterate over all index entries of the stream,
|
||||||
|
// there is one entry per frame (TODO: actually one per field,
|
||||||
|
// if I interprete the documentation correctly...)
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
int lastKeyframePos = 0;
|
||||||
|
int lastKeyframeIndex = 0;
|
||||||
for (uint32 i = 0; i < fIndexSize; i++) {
|
for (uint32 i = 0; i < fIndexSize; i++) {
|
||||||
if ((fIndex[i].chunk_id & 0xffff) == data->chunk_id) {
|
// ignore index entries which are not for this stream
|
||||||
|
if ((fIndex[i].chunk_id & 0xffff) != data->chunk_id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// remember the last known keyframe index/frame
|
||||||
|
if (fIndex[i].flags & AVIIF_KEYFRAME) {
|
||||||
|
lastKeyframePos = pos;
|
||||||
|
lastKeyframeIndex = i;
|
||||||
|
TRACE("keyframe at index %ld, frame %ld (seek: %ld)\n", i,
|
||||||
|
pos, frame_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seekTo & B_MEDIA_SEEK_CLOSEST_BACKWARD) {
|
||||||
|
// use the index and frame of the last keyframe
|
||||||
|
if (pos == frame_pos) {
|
||||||
|
frame_pos = lastKeyframePos;
|
||||||
|
if (!readOnly)
|
||||||
|
data->stream_pos = lastKeyframeIndex;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
} else if (seekTo & B_MEDIA_SEEK_CLOSEST_FORWARD) {
|
||||||
|
// use the index and frame of the last keyframe
|
||||||
|
// if this frame is a keyframe and we at or past
|
||||||
|
// the seek position
|
||||||
|
if (pos >= frame_pos && pos == lastKeyframePos) {
|
||||||
|
frame_pos = lastKeyframePos;
|
||||||
|
if (!readOnly)
|
||||||
|
data->stream_pos = lastKeyframeIndex;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ignore keyframes
|
||||||
if (pos == frame_pos) {
|
if (pos == frame_pos) {
|
||||||
if (!readOnly)
|
if (!readOnly)
|
||||||
data->stream_pos = i;
|
data->stream_pos = i;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
pos++;
|
|
||||||
}
|
}
|
||||||
|
pos++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|||||||
Reference in New Issue
Block a user