Preparation of seek support. Put AVI index handling into different files. Preload the full idx1 (standard) index during file opening.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21388 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, Marcus Overhagen
|
* Copyright (c) 2004-2007, Marcus Overhagen
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
#include "RawFormats.h"
|
#include "RawFormats.h"
|
||||||
#include "avi_reader.h"
|
#include "avi_reader.h"
|
||||||
|
|
||||||
//#define TRACE_AVI_READER
|
#define TRACE_AVI_READER
|
||||||
#ifdef TRACE_AVI_READER
|
#ifdef TRACE_AVI_READER
|
||||||
#define TRACE printf
|
#define TRACE printf
|
||||||
#else
|
#else
|
||||||
@@ -71,7 +71,7 @@ struct avi_cookie
|
|||||||
|
|
||||||
|
|
||||||
aviReader::aviReader()
|
aviReader::aviReader()
|
||||||
: fFile(0)
|
: fFile(NULL)
|
||||||
{
|
{
|
||||||
TRACE("aviReader::aviReader\n");
|
TRACE("aviReader::aviReader\n");
|
||||||
}
|
}
|
||||||
@@ -110,8 +110,8 @@ aviReader::Sniff(int32 *streamCount)
|
|||||||
|
|
||||||
TRACE("aviReader::Sniff: this stream seems to be supported\n");
|
TRACE("aviReader::Sniff: this stream seems to be supported\n");
|
||||||
|
|
||||||
fFile = new OpenDMLFile();
|
fFile = new OpenDMLFile(pos_io_source);
|
||||||
if (B_OK != fFile->SetTo(pos_io_source)) {
|
if (B_OK != fFile->Init()) {
|
||||||
ERROR("aviReader::Sniff: can't setup OpenDMLFile\n");
|
ERROR("aviReader::Sniff: can't setup OpenDMLFile\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
@@ -169,24 +169,24 @@ aviReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
|||||||
|
|
||||||
if (audio_format->format_tag == 0x0001) {// PCM
|
if (audio_format->format_tag == 0x0001) {// PCM
|
||||||
cookie->frame_count = stream_header->length / ((stream_header->sample_size + 7) / 8);
|
cookie->frame_count = stream_header->length / ((stream_header->sample_size + 7) / 8);
|
||||||
TRACE("frame_count %Ld (is PCM)\n", cookie->frame_count);
|
TRACE("audio frame_count %Ld (is PCM)\n", cookie->frame_count);
|
||||||
} else if (stream_header->rate) { // not PCM
|
} else if (stream_header->rate) { // not PCM
|
||||||
cookie->frame_count = (stream_header->length * (int64)audio_format->frames_per_sec) / stream_header->rate;
|
cookie->frame_count = (stream_header->length * (int64)audio_format->frames_per_sec) / stream_header->rate;
|
||||||
TRACE("frame_count %Ld (using rate)\n", cookie->frame_count);
|
TRACE("audio frame_count %Ld (using rate)\n", cookie->frame_count);
|
||||||
} else { // not PCM
|
} else { // not PCM
|
||||||
cookie->frame_count = (stream_header->length * (int64)audio_format->frames_per_sec) / (stream_header->sample_size * audio_format->avg_bytes_per_sec);
|
cookie->frame_count = (stream_header->length * (int64)audio_format->frames_per_sec) / (stream_header->sample_size * audio_format->avg_bytes_per_sec);
|
||||||
TRACE("frame_count %Ld (using fallback)\n", cookie->frame_count);
|
TRACE("audio frame_count %Ld (using fallback)\n", cookie->frame_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream_header->rate && stream_header->scale) {
|
if (stream_header->rate && stream_header->scale) {
|
||||||
cookie->duration = (1000000LL * (int64)stream_header->length * (int64)stream_header->scale) / stream_header->rate;
|
cookie->duration = (1000000LL * (int64)stream_header->length * (int64)stream_header->scale) / stream_header->rate;
|
||||||
TRACE("duration %.6f (%Ld) (using scale & rate)\n", cookie->duration / 1E6, cookie->duration);
|
TRACE("audio duration %.6f (%Ld) (using scale & rate)\n", cookie->duration / 1E6, cookie->duration);
|
||||||
} else if (stream_header->rate) {
|
} else if (stream_header->rate) {
|
||||||
cookie->duration = (1000000LL * (int64)stream_header->length) / stream_header->rate;
|
cookie->duration = (1000000LL * (int64)stream_header->length) / stream_header->rate;
|
||||||
TRACE("duration %.6f (%Ld) (using rate)\n", cookie->duration / 1E6, cookie->duration);
|
TRACE("audio duration %.6f (%Ld) (using rate)\n", cookie->duration / 1E6, cookie->duration);
|
||||||
} else {
|
} else {
|
||||||
cookie->duration = fFile->Duration();
|
cookie->duration = fFile->Duration();
|
||||||
TRACE("duration %.6f (%Ld) (using fallback)\n", cookie->duration / 1E6, cookie->duration);
|
TRACE("audio duration %.6f (%Ld) (using fallback)\n", cookie->duration / 1E6, cookie->duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie->audio = true;
|
cookie->audio = true;
|
||||||
@@ -195,19 +195,19 @@ aviReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
|||||||
if (stream_header->scale && stream_header->rate && stream_header->sample_size) {
|
if (stream_header->scale && stream_header->rate && stream_header->sample_size) {
|
||||||
cookie->bytes_per_sec_rate = stream_header->rate * stream_header->sample_size;
|
cookie->bytes_per_sec_rate = stream_header->rate * stream_header->sample_size;
|
||||||
cookie->bytes_per_sec_scale = stream_header->scale;
|
cookie->bytes_per_sec_scale = stream_header->scale;
|
||||||
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using both)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
TRACE("audio bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using both)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
||||||
} else if (audio_format->avg_bytes_per_sec) {
|
} else if (audio_format->avg_bytes_per_sec) {
|
||||||
cookie->bytes_per_sec_rate = audio_format->avg_bytes_per_sec;
|
cookie->bytes_per_sec_rate = audio_format->avg_bytes_per_sec;
|
||||||
cookie->bytes_per_sec_scale = 1;
|
cookie->bytes_per_sec_scale = 1;
|
||||||
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using avg_bytes_per_sec)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
TRACE("audio bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using avg_bytes_per_sec)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
||||||
} else if (stream_header->rate) {
|
} else if (stream_header->rate) {
|
||||||
cookie->bytes_per_sec_rate = stream_header->rate;
|
cookie->bytes_per_sec_rate = stream_header->rate;
|
||||||
cookie->bytes_per_sec_scale = 1;
|
cookie->bytes_per_sec_scale = 1;
|
||||||
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
TRACE("audio bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
||||||
} else {
|
} else {
|
||||||
cookie->bytes_per_sec_rate = 128000;
|
cookie->bytes_per_sec_rate = 128000;
|
||||||
cookie->bytes_per_sec_scale = 8;
|
cookie->bytes_per_sec_scale = 8;
|
||||||
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using fallback)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
TRACE("audio bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using fallback)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_format->format_tag == 0x0001) {
|
if (audio_format->format_tag == 0x0001) {
|
||||||
@@ -291,8 +291,8 @@ aviReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
|||||||
cookie->frame_count = stream_header->length;
|
cookie->frame_count = stream_header->length;
|
||||||
cookie->duration = (cookie->frame_count * (int64)cookie->frames_per_sec_scale * 1000000LL) / cookie->frames_per_sec_rate;
|
cookie->duration = (cookie->frame_count * (int64)cookie->frames_per_sec_scale * 1000000LL) / cookie->frames_per_sec_rate;
|
||||||
|
|
||||||
TRACE("frame_count %Ld\n", cookie->frame_count);
|
TRACE("video frame_count %Ld\n", cookie->frame_count);
|
||||||
TRACE("duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration);
|
TRACE("video duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration);
|
||||||
|
|
||||||
description.family = B_AVI_FORMAT_FAMILY;
|
description.family = B_AVI_FORMAT_FAMILY;
|
||||||
if (stream_header->fourcc_handler == 'ekaf' || stream_header->fourcc_handler == 0) // 'fake' or 0 fourcc => used compression id
|
if (stream_header->fourcc_handler == 'ekaf' || stream_header->fourcc_handler == 0) // 'fake' or 0 fourcc => used compression id
|
||||||
@@ -383,9 +383,14 @@ aviReader::GetNextChunk(void *_cookie,
|
|||||||
avi_cookie *cookie = (avi_cookie *)_cookie;
|
avi_cookie *cookie = (avi_cookie *)_cookie;
|
||||||
|
|
||||||
int64 start; uint32 size; bool keyframe;
|
int64 start; uint32 size; bool keyframe;
|
||||||
if (!fFile->GetNextChunkInfo(cookie->stream, &start, &size, &keyframe))
|
if (fFile->GetNextChunkInfo(cookie->stream, &start, &size, &keyframe) < B_OK)
|
||||||
return B_LAST_BUFFER_ERROR;
|
return B_LAST_BUFFER_ERROR;
|
||||||
|
|
||||||
|
if (size > 0x200000) { // 2 MB
|
||||||
|
ERROR("stream %d: frame too big: %u byte\n", size);
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
if (cookie->buffer_size < size) {
|
if (cookie->buffer_size < size) {
|
||||||
delete [] cookie->buffer;
|
delete [] cookie->buffer;
|
||||||
cookie->buffer_size = (size + 15) & ~15;
|
cookie->buffer_size = (size + 15) & ~15;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2004, Marcus Overhagen
|
* Copyright (c) 2004-2007, Marcus Overhagen
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
#define _AVI_READER_H
|
#define _AVI_READER_H
|
||||||
|
|
||||||
#include "ReaderPlugin.h"
|
#include "ReaderPlugin.h"
|
||||||
#include "libOpenDML/OpenDMLFile.h"
|
#include "OpenDMLFile.h"
|
||||||
|
|
||||||
class aviReader : public Reader
|
class aviReader : public Reader
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "FallbackIndex.h"
|
||||||
|
|
||||||
|
|
||||||
|
FallbackIndex::FallbackIndex(BPositionIO *source, OpenDMLParser *parser)
|
||||||
|
: Index(source, parser)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FallbackIndex::~FallbackIndex()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FallbackIndex::Init()
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FallbackIndex::GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FallbackIndex::Seek(int stream_index, uint32 seekTo, int64 *frame, bigtime_t *time)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _FALLBACK_INDEX_H
|
||||||
|
#define _FALLBACK_INDEX_H
|
||||||
|
|
||||||
|
#include "Index.h"
|
||||||
|
|
||||||
|
class FallbackIndex : public Index
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FallbackIndex(BPositionIO *source, OpenDMLParser *parser);
|
||||||
|
~FallbackIndex();
|
||||||
|
|
||||||
|
status_t Init();
|
||||||
|
|
||||||
|
status_t GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe);
|
||||||
|
status_t Seek(int stream_index, uint32 seekTo, int64 *frame, bigtime_t *time);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "Index.h"
|
||||||
|
|
||||||
|
Index::Index(BPositionIO *source, OpenDMLParser *parser)
|
||||||
|
: fSource(source)
|
||||||
|
, fParser(parser)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Index::~Index()
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _INDEX_H
|
||||||
|
#define _INDEX_H
|
||||||
|
|
||||||
|
class OpenDMLParser;
|
||||||
|
|
||||||
|
class Index
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Index(BPositionIO *source, OpenDMLParser *parser);
|
||||||
|
virtual ~Index();
|
||||||
|
|
||||||
|
virtual status_t Init() = 0;
|
||||||
|
|
||||||
|
virtual status_t GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe) = 0;
|
||||||
|
virtual status_t Seek(int stream_index, uint32 seekTo, int64 *frame, bigtime_t *time) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BPositionIO * fSource;
|
||||||
|
OpenDMLParser * fParser;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
SubDir HAIKU_TOP src add-ons media plugins avi_reader libOpenDML ;
|
SubDir HAIKU_TOP src add-ons media plugins avi_reader libOpenDML ;
|
||||||
|
|
||||||
|
UsePrivateHeaders media ;
|
||||||
|
|
||||||
StaticLibrary libopendml.a :
|
StaticLibrary libopendml.a :
|
||||||
OpenDMLFile.cpp
|
OpenDMLFile.cpp
|
||||||
OpenDMLParser.cpp
|
OpenDMLParser.cpp
|
||||||
|
Index.cpp
|
||||||
|
OpenDMLIndex.cpp
|
||||||
|
StandardIndex.cpp
|
||||||
|
FallbackIndex.cpp
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "OpenDMLFile.h"
|
#include "OpenDMLFile.h"
|
||||||
|
#include "OpenDMLIndex.h"
|
||||||
|
#include "StandardIndex.h"
|
||||||
|
#include "FallbackIndex.h"
|
||||||
|
|
||||||
#define TRACE_ODML_FILE
|
#define TRACE_ODML_FILE
|
||||||
#ifdef TRACE_ODML_FILE
|
#ifdef TRACE_ODML_FILE
|
||||||
@@ -34,6 +37,7 @@
|
|||||||
|
|
||||||
#define ERROR(a...) fprintf(stderr, a)
|
#define ERROR(a...) fprintf(stderr, a)
|
||||||
|
|
||||||
|
#if 0
|
||||||
#define INDEX_CHUNK_SIZE 32768
|
#define INDEX_CHUNK_SIZE 32768
|
||||||
|
|
||||||
struct OpenDMLFile::stream_data
|
struct OpenDMLFile::stream_data
|
||||||
@@ -62,19 +66,19 @@ struct OpenDMLFile::stream_data
|
|||||||
int index_chunk_entry_count;
|
int index_chunk_entry_count;
|
||||||
int index_chunk_entry_pos;
|
int index_chunk_entry_pos;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
OpenDMLFile::OpenDMLFile()
|
OpenDMLFile::OpenDMLFile(BPositionIO *source)
|
||||||
: fSource(0),
|
: fSource(source)
|
||||||
fParser(0),
|
, fParser(NULL)
|
||||||
fStreamCount(0),
|
, fIndex(NULL)
|
||||||
fStreamData(0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenDMLFile::~OpenDMLFile()
|
OpenDMLFile::~OpenDMLFile()
|
||||||
{
|
{
|
||||||
delete fParser;
|
delete fParser;
|
||||||
delete [] fStreamData;
|
delete fIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
@@ -88,10 +92,8 @@ OpenDMLFile::IsSupported(BPositionIO *source)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
OpenDMLFile::SetTo(BPositionIO *source)
|
OpenDMLFile::Init()
|
||||||
{
|
{
|
||||||
fSource = source;
|
|
||||||
delete fParser;
|
|
||||||
fParser = new OpenDMLParser(fSource);
|
fParser = new OpenDMLParser(fSource);
|
||||||
|
|
||||||
if (fParser->Parse() < B_OK) {
|
if (fParser->Parse() < B_OK) {
|
||||||
@@ -103,28 +105,40 @@ OpenDMLFile::SetTo(BPositionIO *source)
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fParser->StreamCount() != 0 && fParser->StandardIndexSize() == 0) {
|
if (fParser->StreamCount() == 0) {
|
||||||
TRACE("OpenDMLFile::SetTo file has no standard avi index\n");
|
ERROR("OpenDMLFile::SetTo: no streams found\n");
|
||||||
bool found_odml_index = false;
|
}
|
||||||
for (int i = 0; i < fParser->StreamCount(); i++) {
|
|
||||||
if (fParser->StreamInfo(i)->odml_index_size != 0) {
|
if (fParser->StreamInfo(0)->odml_index_size != 0) {
|
||||||
found_odml_index = true;
|
fIndex = new OpenDMLIndex(fSource, fParser);
|
||||||
break;
|
if (fIndex->Init() < B_OK) {
|
||||||
}
|
delete fIndex;
|
||||||
|
fIndex = NULL;
|
||||||
}
|
}
|
||||||
if (!found_odml_index) {
|
}
|
||||||
ERROR("OpenDMLFile::SetTo file has no standard avi index, and no OpenDML track index found\n");
|
if (!fIndex && fParser->StandardIndexSize() != 0) {
|
||||||
|
fIndex = new StandardIndex(fSource, fParser);
|
||||||
|
if (fIndex->Init() < B_OK) {
|
||||||
|
delete fIndex;
|
||||||
|
fIndex = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!fIndex) {
|
||||||
|
fIndex = new FallbackIndex(fSource, fParser);
|
||||||
|
if (fIndex->Init() < B_OK) {
|
||||||
|
delete fIndex;
|
||||||
|
fIndex = NULL;
|
||||||
|
TRACE("OpenDMLFile::SetTo: init of fallback index failed!\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("OpenDMLFile::SetTo: this is a %s AVI file with %d streams\n", fParser->OdmlExtendedHeader() ? "OpenDML" : "standard", fParser->StreamCount());
|
TRACE("OpenDMLFile::SetTo: this is a %s AVI file with %d streams\n", fParser->OdmlExtendedHeader() ? "OpenDML" : "standard", fParser->StreamCount());
|
||||||
|
|
||||||
InitData();
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void
|
void
|
||||||
OpenDMLFile::InitData()
|
OpenDMLFile::InitData()
|
||||||
{
|
{
|
||||||
@@ -375,22 +389,18 @@ OpenDMLFile::AviGetNextChunkInfo(int stream_index, int64 *start, uint32 *size, b
|
|||||||
TRACE("OpenDMLFile::AviGetNextChunkInfo: index end reached\n");
|
TRACE("OpenDMLFile::AviGetNextChunkInfo: index end reached\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
status_t
|
||||||
OpenDMLFile::GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe)
|
OpenDMLFile::GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe)
|
||||||
{
|
{
|
||||||
stream_data *data = &fStreamData[stream_index];
|
return fIndex->GetNextChunkInfo(stream_index, start, size, keyframe);
|
||||||
if (data->has_standard_index)
|
|
||||||
return AviGetNextChunkInfo(stream_index, start, size, keyframe);
|
|
||||||
if (data->has_odml_index)
|
|
||||||
return OdmlGetNextChunkInfo(stream_index, start, size, keyframe);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
OpenDMLFile::StreamCount()
|
OpenDMLFile::StreamCount()
|
||||||
{
|
{
|
||||||
return fStreamCount;
|
return fParser->StreamCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
bigtime_t
|
bigtime_t
|
||||||
@@ -416,13 +426,13 @@ OpenDMLFile::FrameCount()
|
|||||||
bool
|
bool
|
||||||
OpenDMLFile::IsVideo(int stream_index)
|
OpenDMLFile::IsVideo(int stream_index)
|
||||||
{
|
{
|
||||||
return fStreamData[stream_index].info->is_video;
|
return fParser->StreamInfo(stream_index)->is_video;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OpenDMLFile::IsAudio(int stream_index)
|
OpenDMLFile::IsAudio(int stream_index)
|
||||||
{
|
{
|
||||||
return fStreamData[stream_index].info->is_audio;
|
return fParser->StreamInfo(stream_index)->is_audio;
|
||||||
}
|
}
|
||||||
|
|
||||||
const avi_main_header *
|
const avi_main_header *
|
||||||
@@ -434,25 +444,25 @@ OpenDMLFile::AviMainHeader()
|
|||||||
const wave_format_ex *
|
const wave_format_ex *
|
||||||
OpenDMLFile::AudioFormat(int stream_index, size_t *size /* = 0*/)
|
OpenDMLFile::AudioFormat(int stream_index, size_t *size /* = 0*/)
|
||||||
{
|
{
|
||||||
if (!fStreamData[stream_index].info->is_audio)
|
if (!fParser->StreamInfo(stream_index)->is_audio)
|
||||||
return 0;
|
return 0;
|
||||||
if (!fStreamData[stream_index].info->audio_format)
|
if (!fParser->StreamInfo(stream_index)->audio_format)
|
||||||
return 0;
|
return 0;
|
||||||
if (size)
|
if (size)
|
||||||
*size = fStreamData[stream_index].info->audio_format_size;
|
*size = fParser->StreamInfo(stream_index)->audio_format_size;
|
||||||
return fStreamData[stream_index].info->audio_format;
|
return fParser->StreamInfo(stream_index)->audio_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bitmap_info_header *
|
const bitmap_info_header *
|
||||||
OpenDMLFile::VideoFormat(int stream_index)
|
OpenDMLFile::VideoFormat(int stream_index)
|
||||||
{
|
{
|
||||||
return (fStreamData[stream_index].info->is_video && fStreamData[stream_index].info->video_format_valid) ?
|
return (fParser->StreamInfo(stream_index)->is_video && fParser->StreamInfo(stream_index)->video_format_valid) ?
|
||||||
&fStreamData[stream_index].info->video_format : 0;
|
&fParser->StreamInfo(stream_index)->video_format : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const avi_stream_header *
|
const avi_stream_header *
|
||||||
OpenDMLFile::StreamFormat(int stream_index)
|
OpenDMLFile::StreamFormat(int stream_index)
|
||||||
{
|
{
|
||||||
return (fStreamData[stream_index].info->stream_header_valid) ?
|
return (fParser->StreamInfo(stream_index)->stream_header_valid) ?
|
||||||
&fStreamData[stream_index].info->stream_header : 0;
|
&fParser->StreamInfo(stream_index)->stream_header : 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,24 +27,25 @@
|
|||||||
|
|
||||||
#include <DataIO.h>
|
#include <DataIO.h>
|
||||||
#include "OpenDMLParser.h"
|
#include "OpenDMLParser.h"
|
||||||
|
#include "Index.h"
|
||||||
|
|
||||||
class OpenDMLFile
|
class OpenDMLFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OpenDMLFile();
|
OpenDMLFile(BPositionIO *source);
|
||||||
~OpenDMLFile();
|
~OpenDMLFile();
|
||||||
|
|
||||||
static bool IsSupported(BPositionIO *source);
|
static bool IsSupported(BPositionIO *source);
|
||||||
|
|
||||||
status_t SetTo(BPositionIO *source);
|
status_t Init();
|
||||||
|
|
||||||
int StreamCount();
|
int StreamCount();
|
||||||
|
|
||||||
bigtime_t Duration();
|
bigtime_t Duration();
|
||||||
uint32 FrameCount();
|
uint32 FrameCount();
|
||||||
|
|
||||||
bool IsVideo(int stream_index);
|
bool IsVideo(int stream_index);
|
||||||
bool IsAudio(int stream_index);
|
bool IsAudio(int stream_index);
|
||||||
|
|
||||||
const avi_main_header *AviMainHeader();
|
const avi_main_header *AviMainHeader();
|
||||||
|
|
||||||
@@ -52,27 +53,14 @@ public:
|
|||||||
const bitmap_info_header * VideoFormat(int stream_index);
|
const bitmap_info_header * VideoFormat(int stream_index);
|
||||||
const avi_stream_header * StreamFormat(int stream_index);
|
const avi_stream_header * StreamFormat(int stream_index);
|
||||||
|
|
||||||
bool GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe);
|
status_t GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe);
|
||||||
|
|
||||||
BPositionIO *Source() { return fSource; }
|
BPositionIO *Source() { return fSource; }
|
||||||
|
|
||||||
private:
|
|
||||||
void InitData();
|
|
||||||
|
|
||||||
bool OdmlReadIndexChunk(int stream_index);
|
|
||||||
bool OdmlReadIndexInfo(int stream_index);
|
|
||||||
bool OdmlGetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe);
|
|
||||||
|
|
||||||
bool AviGetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BPositionIO * fSource;
|
BPositionIO * fSource;
|
||||||
OpenDMLParser * fParser;
|
OpenDMLParser * fParser;
|
||||||
|
Index * fIndex;
|
||||||
struct stream_data;
|
|
||||||
|
|
||||||
int fStreamCount;
|
|
||||||
stream_data * fStreamData;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "OpenDMLIndex.h"
|
||||||
|
|
||||||
|
|
||||||
|
OpenDMLIndex::OpenDMLIndex(BPositionIO *source, OpenDMLParser *parser)
|
||||||
|
: Index(source, parser)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OpenDMLIndex::~OpenDMLIndex()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
OpenDMLIndex::Init()
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
OpenDMLIndex::GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
OpenDMLIndex::Seek(int stream_index, uint32 seekTo, int64 *frame, bigtime_t *time)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _OPEN_DML_INDEX_H
|
||||||
|
#define _OPEN_DML_INDEX_H
|
||||||
|
|
||||||
|
#include "Index.h"
|
||||||
|
|
||||||
|
class OpenDMLIndex : public Index
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OpenDMLIndex(BPositionIO *source, OpenDMLParser *parser);
|
||||||
|
~OpenDMLIndex();
|
||||||
|
|
||||||
|
status_t Init();
|
||||||
|
|
||||||
|
status_t GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe);
|
||||||
|
status_t Seek(int stream_index, uint32 seekTo, int64 *frame, bigtime_t *time);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
#include <DataIO.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <new>
|
||||||
|
#include "ReaderPlugin.h" // B_MEDIA_*
|
||||||
|
#include "StandardIndex.h"
|
||||||
|
#include "OpenDMLParser.h"
|
||||||
|
|
||||||
|
#include <StopWatch.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct StandardIndex::stream_data
|
||||||
|
{
|
||||||
|
uint32 chunk_id;
|
||||||
|
uint32 pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
StandardIndex::StandardIndex(BPositionIO *source, OpenDMLParser *parser)
|
||||||
|
: Index(source, parser)
|
||||||
|
, fIndex(NULL)
|
||||||
|
, fIndexSize(0)
|
||||||
|
, fStreamData(NULL)
|
||||||
|
, fStreamCount(parser->StreamCount())
|
||||||
|
, fDataOffset(parser->MovieListStart() - 4)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StandardIndex::~StandardIndex()
|
||||||
|
{
|
||||||
|
delete [] fIndex;
|
||||||
|
delete [] fStreamData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
StandardIndex::Init()
|
||||||
|
{
|
||||||
|
uint32 indexBytes = fParser->StandardIndexSize();
|
||||||
|
fIndexSize = indexBytes / sizeof(avi_standard_index_entry);
|
||||||
|
indexBytes = fIndexSize * sizeof(avi_standard_index_entry);
|
||||||
|
|
||||||
|
{ BStopWatch w("StandardIndex::Init: malloc");
|
||||||
|
|
||||||
|
if (indexBytes > 0x1900000) { // 25 MB
|
||||||
|
printf("StandardIndex::Init index is way too big\n");
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fIndexSize == 0) {
|
||||||
|
printf("StandardIndex::Init index is empty\n");
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fIndex = new (std::nothrow) avi_standard_index_entry[fIndexSize];
|
||||||
|
if (fIndex == NULL) {
|
||||||
|
printf("StandardIndex::Init out of memory\n");
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ BStopWatch w("StandardIndex::Init: file read");
|
||||||
|
|
||||||
|
if (indexBytes != fSource->ReadAt(fParser->StandardIndexStart(), fIndex, indexBytes)) {
|
||||||
|
printf("StandardIndex::Init file reading failed\n");
|
||||||
|
delete [] fIndex;
|
||||||
|
fIndex = NULL;
|
||||||
|
return B_IO_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fStreamData = new stream_data[fStreamCount];
|
||||||
|
for (int i = 0; i < fStreamCount; i++) {
|
||||||
|
fStreamData[i].chunk_id = i / 10 + '0' + (i % 10 + '0') * 256;
|
||||||
|
fStreamData[i].pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//DumpIndex();
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
StandardIndex::DumpIndex()
|
||||||
|
{
|
||||||
|
uint32 chunk = fIndex->chunk_id;
|
||||||
|
int count = 0;
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
printf("StandardIndex::DumpIndex %u entries\n", fIndexSize);
|
||||||
|
for (int i = 0; i < fIndexSize; i++) {
|
||||||
|
count++;
|
||||||
|
if (chunk != fIndex[i].chunk_id) {
|
||||||
|
printf("%3d %c%c%c%c", count, FOURCC_PARAM(chunk));
|
||||||
|
chunk = fIndex[i].chunk_id;
|
||||||
|
count = 0;
|
||||||
|
if (++pos % 8 == 0)
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count)
|
||||||
|
printf("%3d %c%c%c%c", count, FOURCC_PARAM(chunk));
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
StandardIndex::GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe)
|
||||||
|
{
|
||||||
|
stream_data *data = &fStreamData[stream_index];
|
||||||
|
while (data->pos < fIndexSize) {
|
||||||
|
if ((fIndex[data->pos].chunk_id & 0xffff) == data->chunk_id) {
|
||||||
|
*keyframe = fIndex[data->pos].flags & AVIIF_KEYFRAME;
|
||||||
|
*start = fDataOffset + fIndex[data->pos].chunk_offset + 8; // skip 8 bytes (chunk id + chunk size)
|
||||||
|
*size = fIndex[data->pos].chunk_length;
|
||||||
|
data->pos++;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
data->pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
StandardIndex::Seek(int stream_index, uint32 seekTo, int64 *frame, bigtime_t *time)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
printf("StandardIndex::Seek: seekTo%s%s%s%s, time %Ld, frame %Ld\n",
|
||||||
|
(seekTo & B_MEDIA_SEEK_TO_TIME) ? " B_MEDIA_SEEK_TO_TIME" : "",
|
||||||
|
(seekTo & B_MEDIA_SEEK_TO_FRAME) ? " B_MEDIA_SEEK_TO_FRAME" : "",
|
||||||
|
(seekTo & B_MEDIA_SEEK_CLOSEST_FORWARD) ? " B_MEDIA_SEEK_CLOSEST_FORWARD" : "",
|
||||||
|
(seekTo & B_MEDIA_SEEK_CLOSEST_BACKWARD) ? " B_MEDIA_SEEK_CLOSEST_BACKWARD" : "");
|
||||||
|
*/
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2007, Marcus Overhagen
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||||
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _STANDARD_INDEX_H
|
||||||
|
#define _STANDARD_INDEX_H
|
||||||
|
|
||||||
|
#include "Index.h"
|
||||||
|
#include "avi.h"
|
||||||
|
|
||||||
|
class StandardIndex : public Index
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StandardIndex(BPositionIO *source, OpenDMLParser *parser);
|
||||||
|
~StandardIndex();
|
||||||
|
|
||||||
|
status_t Init();
|
||||||
|
|
||||||
|
status_t GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe);
|
||||||
|
status_t Seek(int stream_index, uint32 seekTo, int64 *frame, bigtime_t *time);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DumpIndex();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct stream_data;
|
||||||
|
avi_standard_index_entry *fIndex;
|
||||||
|
uint32 fIndexSize;
|
||||||
|
stream_data * fStreamData;
|
||||||
|
int fStreamCount;
|
||||||
|
int64 fDataOffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user