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.
|
||||
*
|
||||
* 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
|
||||
Reference in New Issue
Block a user