Implement FindKeyFrame
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26076 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -34,7 +34,7 @@
|
|||||||
#include "matroska_codecs.h"
|
#include "matroska_codecs.h"
|
||||||
#include "matroska_util.h"
|
#include "matroska_util.h"
|
||||||
|
|
||||||
#define TRACE_MKV_READER
|
//#define TRACE_MKV_READER
|
||||||
#ifdef TRACE_MKV_READER
|
#ifdef TRACE_MKV_READER
|
||||||
#define TRACE printf
|
#define TRACE printf
|
||||||
#else
|
#else
|
||||||
@@ -345,26 +345,26 @@ mkvReader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
mkvReader::Seek(void *cookie,
|
mkvReader::Seek(void *cookie, uint32 flags,
|
||||||
uint32 seekTo,
|
|
||||||
int64 *frame, bigtime_t *time)
|
int64 *frame, bigtime_t *time)
|
||||||
{
|
{
|
||||||
|
// Seek to the specified frame or time
|
||||||
mkv_cookie *mkvcookie = (mkv_cookie *)cookie;
|
mkv_cookie *mkvcookie = (mkv_cookie *)cookie;
|
||||||
|
|
||||||
TRACE("mkvReader::Seek: seekTo%s%s%s%s, time %Ld, frame %Ld\n",
|
TRACE("mkvReader::Seek: seekTo%s%s%s%s, time %Ld, frame %Ld\n",
|
||||||
(seekTo & B_MEDIA_SEEK_TO_TIME) ? " B_MEDIA_SEEK_TO_TIME" : "",
|
(flags & B_MEDIA_SEEK_TO_TIME) ? " B_MEDIA_SEEK_TO_TIME" : "",
|
||||||
(seekTo & B_MEDIA_SEEK_TO_FRAME) ? " B_MEDIA_SEEK_TO_FRAME" : "",
|
(flags & B_MEDIA_SEEK_TO_FRAME) ? " B_MEDIA_SEEK_TO_FRAME" : "",
|
||||||
(seekTo & B_MEDIA_SEEK_CLOSEST_FORWARD) ? " B_MEDIA_SEEK_CLOSEST_FORWARD" : "",
|
(flags & B_MEDIA_SEEK_CLOSEST_FORWARD) ? " B_MEDIA_SEEK_CLOSEST_FORWARD" : "",
|
||||||
(seekTo & B_MEDIA_SEEK_CLOSEST_BACKWARD) ? " B_MEDIA_SEEK_CLOSEST_BACKWARD" : "",
|
(flags & B_MEDIA_SEEK_CLOSEST_BACKWARD) ? " B_MEDIA_SEEK_CLOSEST_BACKWARD" : "",
|
||||||
*time, *frame);
|
*time, *frame);
|
||||||
|
|
||||||
if (seekTo & B_MEDIA_SEEK_TO_FRAME) {
|
if (flags & B_MEDIA_SEEK_TO_FRAME) {
|
||||||
*time = bigtime_t(*frame * (1000000.0 / mkvcookie->frame_rate));
|
*time = bigtime_t(*frame * (1000000.0 / mkvcookie->frame_rate));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seekTo & B_MEDIA_SEEK_CLOSEST_BACKWARD) {
|
if (flags & B_MEDIA_SEEK_CLOSEST_BACKWARD) {
|
||||||
mkv_Seek(mkvcookie->file, *time * 1000, MKVF_SEEK_TO_PREV_KEYFRAME);
|
mkv_Seek(mkvcookie->file, *time * 1000, MKVF_SEEK_TO_PREV_KEYFRAME);
|
||||||
} else if (seekTo & B_MEDIA_SEEK_CLOSEST_FORWARD) {
|
} else if (flags & B_MEDIA_SEEK_CLOSEST_FORWARD) {
|
||||||
mkv_Seek(mkvcookie->file, *time * 1000, 0);
|
mkv_Seek(mkvcookie->file, *time * 1000, 0);
|
||||||
mkv_SkipToKeyframe(mkvcookie->file);
|
mkv_SkipToKeyframe(mkvcookie->file);
|
||||||
} else {
|
} else {
|
||||||
@@ -382,6 +382,48 @@ mkvReader::Seek(void *cookie,
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
mkvReader::FindKeyFrame(void* cookie, uint32 flags,
|
||||||
|
int64* frame, bigtime_t* time)
|
||||||
|
{
|
||||||
|
// Find the nearest keyframe to the given time or frame.
|
||||||
|
|
||||||
|
mkv_cookie *mkvcookie = (mkv_cookie *)cookie;
|
||||||
|
|
||||||
|
if (flags & B_MEDIA_SEEK_TO_FRAME) {
|
||||||
|
// convert frame to time as matroska seeks by time
|
||||||
|
*time = bigtime_t(*frame * (1000000.0 / mkvcookie->frame_rate));
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE("mkvReader::FindKeyFrame: seekTo%s%s%s%s, time %Ld, frame %Ld\n",
|
||||||
|
(flags & B_MEDIA_SEEK_TO_TIME) ? " B_MEDIA_SEEK_TO_TIME" : "",
|
||||||
|
(flags & B_MEDIA_SEEK_TO_FRAME) ? " B_MEDIA_SEEK_TO_FRAME" : "",
|
||||||
|
(flags & B_MEDIA_SEEK_CLOSEST_FORWARD) ? " B_MEDIA_SEEK_CLOSEST_FORWARD" : "",
|
||||||
|
(flags & B_MEDIA_SEEK_CLOSEST_BACKWARD) ? " B_MEDIA_SEEK_CLOSEST_BACKWARD" : "",
|
||||||
|
*time, *frame);
|
||||||
|
|
||||||
|
if (flags & B_MEDIA_SEEK_CLOSEST_BACKWARD) {
|
||||||
|
mkv_Seek(mkvcookie->file, *time * 1000, MKVF_SEEK_TO_PREV_KEYFRAME);
|
||||||
|
} else if (flags & B_MEDIA_SEEK_CLOSEST_FORWARD) {
|
||||||
|
mkv_Seek(mkvcookie->file, *time * 1000, 0);
|
||||||
|
mkv_SkipToKeyframe(mkvcookie->file);
|
||||||
|
} else {
|
||||||
|
mkv_Seek(mkvcookie->file, *time * 1000, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 timecode;
|
||||||
|
timecode = mkv_GetLowestQTimecode(mkvcookie->file);
|
||||||
|
if (timecode < 0)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// convert time found to frame
|
||||||
|
*time = timecode / 1000;
|
||||||
|
*frame = get_frame_count_by_frame_rate(timecode, mkvcookie->frame_rate);
|
||||||
|
|
||||||
|
TRACE("Found keyframe at frame %Ld time %Ld\n",*frame,*time);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
mkvReader::GetNextChunk(void *_cookie,
|
mkvReader::GetNextChunk(void *_cookie,
|
||||||
|
|||||||
@@ -36,23 +36,26 @@ public:
|
|||||||
mkvReader();
|
mkvReader();
|
||||||
~mkvReader();
|
~mkvReader();
|
||||||
|
|
||||||
const char *Copyright();
|
virtual const char *Copyright();
|
||||||
|
|
||||||
status_t Sniff(int32 *streamCount);
|
virtual status_t Sniff(int32 *streamCount);
|
||||||
|
|
||||||
void GetFileFormatInfo(media_file_format *mff);
|
virtual void GetFileFormatInfo(media_file_format *mff);
|
||||||
|
|
||||||
status_t AllocateCookie(int32 streamNumber, void **cookie);
|
virtual status_t AllocateCookie(int32 streamNumber, void **cookie);
|
||||||
status_t FreeCookie(void *cookie);
|
|
||||||
|
|
||||||
status_t GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
|
virtual status_t FreeCookie(void *cookie);
|
||||||
|
|
||||||
|
virtual status_t GetStreamInfo(void *cookie, int64 *frameCount, bigtime_t *duration,
|
||||||
media_format *format, const void **infoBuffer, size_t *infoSize);
|
media_format *format, const void **infoBuffer, size_t *infoSize);
|
||||||
|
|
||||||
status_t Seek(void *cookie,
|
virtual status_t Seek(void *cookie, uint32 flags,
|
||||||
uint32 seekTo,
|
|
||||||
int64 *frame, bigtime_t *time);
|
int64 *frame, bigtime_t *time);
|
||||||
|
|
||||||
status_t GetNextChunk(void *cookie,
|
virtual status_t FindKeyFrame(void* cookie, uint32 flags,
|
||||||
|
int64* frame, bigtime_t* time);
|
||||||
|
|
||||||
|
virtual status_t GetNextChunk(void *cookie,
|
||||||
const void **chunkBuffer, size_t *chunkSize,
|
const void **chunkBuffer, size_t *chunkSize,
|
||||||
media_header *mediaHeader);
|
media_header *mediaHeader);
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user