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:
Marcus Overhagen
2007-06-10 23:13:28 +00:00
parent e31380534b
commit 59ab99e7c6
13 changed files with 594 additions and 83 deletions
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, Marcus Overhagen
* Copyright (c) 2004-2007, Marcus Overhagen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -32,7 +32,7 @@
#include "RawFormats.h"
#include "avi_reader.h"
//#define TRACE_AVI_READER
#define TRACE_AVI_READER
#ifdef TRACE_AVI_READER
#define TRACE printf
#else
@@ -71,7 +71,7 @@ struct avi_cookie
aviReader::aviReader()
: fFile(0)
: fFile(NULL)
{
TRACE("aviReader::aviReader\n");
}
@@ -110,8 +110,8 @@ aviReader::Sniff(int32 *streamCount)
TRACE("aviReader::Sniff: this stream seems to be supported\n");
fFile = new OpenDMLFile();
if (B_OK != fFile->SetTo(pos_io_source)) {
fFile = new OpenDMLFile(pos_io_source);
if (B_OK != fFile->Init()) {
ERROR("aviReader::Sniff: can't setup OpenDMLFile\n");
return B_ERROR;
}
@@ -169,24 +169,24 @@ aviReader::AllocateCookie(int32 streamNumber, void **_cookie)
if (audio_format->format_tag == 0x0001) {// PCM
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
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
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) {
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) {
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 {
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;
@@ -195,19 +195,19 @@ aviReader::AllocateCookie(int32 streamNumber, void **_cookie)
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_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) {
cookie->bytes_per_sec_rate = audio_format->avg_bytes_per_sec;
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) {
cookie->bytes_per_sec_rate = stream_header->rate;
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 {
cookie->bytes_per_sec_rate = 128000;
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) {
@@ -291,8 +291,8 @@ aviReader::AllocateCookie(int32 streamNumber, void **_cookie)
cookie->frame_count = stream_header->length;
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("duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration);
TRACE("video frame_count %Ld\n", cookie->frame_count);
TRACE("video duration %.6f (%Ld)\n", cookie->duration / 1E6, cookie->duration);
description.family = B_AVI_FORMAT_FAMILY;
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;
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;
if (size > 0x200000) { // 2 MB
ERROR("stream %d: frame too big: %u byte\n", size);
return B_NO_MEMORY;
}
if (cookie->buffer_size < size) {
delete [] cookie->buffer;
cookie->buffer_size = (size + 15) & ~15;
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, Marcus Overhagen
* Copyright (c) 2004-2007, Marcus Overhagen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -26,7 +26,7 @@
#define _AVI_READER_H
#include "ReaderPlugin.h"
#include "libOpenDML/OpenDMLFile.h"
#include "OpenDMLFile.h"
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 ;
UsePrivateHeaders media ;
StaticLibrary libopendml.a :
OpenDMLFile.cpp
OpenDMLParser.cpp
Index.cpp
OpenDMLIndex.cpp
StandardIndex.cpp
FallbackIndex.cpp
;
@@ -24,6 +24,9 @@
*/
#include <stdio.h>
#include "OpenDMLFile.h"
#include "OpenDMLIndex.h"
#include "StandardIndex.h"
#include "FallbackIndex.h"
#define TRACE_ODML_FILE
#ifdef TRACE_ODML_FILE
@@ -34,6 +37,7 @@
#define ERROR(a...) fprintf(stderr, a)
#if 0
#define INDEX_CHUNK_SIZE 32768
struct OpenDMLFile::stream_data
@@ -62,19 +66,19 @@ struct OpenDMLFile::stream_data
int index_chunk_entry_count;
int index_chunk_entry_pos;
};
#endif
OpenDMLFile::OpenDMLFile()
: fSource(0),
fParser(0),
fStreamCount(0),
fStreamData(0)
OpenDMLFile::OpenDMLFile(BPositionIO *source)
: fSource(source)
, fParser(NULL)
, fIndex(NULL)
{
}
OpenDMLFile::~OpenDMLFile()
{
delete fParser;
delete [] fStreamData;
delete fIndex;
}
/* static */ bool
@@ -88,10 +92,8 @@ OpenDMLFile::IsSupported(BPositionIO *source)
}
status_t
OpenDMLFile::SetTo(BPositionIO *source)
OpenDMLFile::Init()
{
fSource = source;
delete fParser;
fParser = new OpenDMLParser(fSource);
if (fParser->Parse() < B_OK) {
@@ -103,28 +105,40 @@ OpenDMLFile::SetTo(BPositionIO *source)
return B_ERROR;
}
if (fParser->StreamCount() != 0 && fParser->StandardIndexSize() == 0) {
TRACE("OpenDMLFile::SetTo file has no standard avi index\n");
bool found_odml_index = false;
for (int i = 0; i < fParser->StreamCount(); i++) {
if (fParser->StreamInfo(i)->odml_index_size != 0) {
found_odml_index = true;
break;
}
if (fParser->StreamCount() == 0) {
ERROR("OpenDMLFile::SetTo: no streams found\n");
}
if (fParser->StreamInfo(0)->odml_index_size != 0) {
fIndex = new OpenDMLIndex(fSource, fParser);
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;
}
}
TRACE("OpenDMLFile::SetTo: this is a %s AVI file with %d streams\n", fParser->OdmlExtendedHeader() ? "OpenDML" : "standard", fParser->StreamCount());
InitData();
return B_OK;
}
#if 0
void
OpenDMLFile::InitData()
{
@@ -375,22 +389,18 @@ OpenDMLFile::AviGetNextChunkInfo(int stream_index, int64 *start, uint32 *size, b
TRACE("OpenDMLFile::AviGetNextChunkInfo: index end reached\n");
return false;
}
#endif
bool
status_t
OpenDMLFile::GetNextChunkInfo(int stream_index, int64 *start, uint32 *size, bool *keyframe)
{
stream_data *data = &fStreamData[stream_index];
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;
return fIndex->GetNextChunkInfo(stream_index, start, size, keyframe);
}
int
OpenDMLFile::StreamCount()
{
return fStreamCount;
return fParser->StreamCount();
}
bigtime_t
@@ -416,13 +426,13 @@ OpenDMLFile::FrameCount()
bool
OpenDMLFile::IsVideo(int stream_index)
{
return fStreamData[stream_index].info->is_video;
return fParser->StreamInfo(stream_index)->is_video;
}
bool
OpenDMLFile::IsAudio(int stream_index)
{
return fStreamData[stream_index].info->is_audio;
return fParser->StreamInfo(stream_index)->is_audio;
}
const avi_main_header *
@@ -434,25 +444,25 @@ OpenDMLFile::AviMainHeader()
const wave_format_ex *
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;
if (!fStreamData[stream_index].info->audio_format)
if (!fParser->StreamInfo(stream_index)->audio_format)
return 0;
if (size)
*size = fStreamData[stream_index].info->audio_format_size;
return fStreamData[stream_index].info->audio_format;
*size = fParser->StreamInfo(stream_index)->audio_format_size;
return fParser->StreamInfo(stream_index)->audio_format;
}
const bitmap_info_header *
OpenDMLFile::VideoFormat(int stream_index)
{
return (fStreamData[stream_index].info->is_video && fStreamData[stream_index].info->video_format_valid) ?
&fStreamData[stream_index].info->video_format : 0;
return (fParser->StreamInfo(stream_index)->is_video && fParser->StreamInfo(stream_index)->video_format_valid) ?
&fParser->StreamInfo(stream_index)->video_format : 0;
}
const avi_stream_header *
OpenDMLFile::StreamFormat(int stream_index)
{
return (fStreamData[stream_index].info->stream_header_valid) ?
&fStreamData[stream_index].info->stream_header : 0;
return (fParser->StreamInfo(stream_index)->stream_header_valid) ?
&fParser->StreamInfo(stream_index)->stream_header : 0;
}
@@ -27,24 +27,25 @@
#include <DataIO.h>
#include "OpenDMLParser.h"
#include "Index.h"
class OpenDMLFile
{
public:
OpenDMLFile();
~OpenDMLFile();
OpenDMLFile(BPositionIO *source);
~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();
uint32 FrameCount();
bigtime_t Duration();
uint32 FrameCount();
bool IsVideo(int stream_index);
bool IsAudio(int stream_index);
bool IsVideo(int stream_index);
bool IsAudio(int stream_index);
const avi_main_header *AviMainHeader();
@@ -52,27 +53,14 @@ public:
const bitmap_info_header * VideoFormat(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; }
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:
BPositionIO * fSource;
OpenDMLParser * fParser;
struct stream_data;
int fStreamCount;
stream_data * fStreamData;
Index * fIndex;
};
#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