From 59ab99e7c6512a35ecf4079d6247c65d3e42bf3f Mon Sep 17 00:00:00 2001 From: Marcus Overhagen Date: Sun, 10 Jun 2007 23:13:28 +0000 Subject: [PATCH] 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 --- .../media/plugins/avi_reader/avi_reader.cpp | 41 +++-- .../media/plugins/avi_reader/avi_reader.h | 4 +- .../avi_reader/libOpenDML/FallbackIndex.cpp | 59 +++++++ .../avi_reader/libOpenDML/FallbackIndex.h | 42 +++++ .../plugins/avi_reader/libOpenDML/Index.cpp | 38 ++++ .../plugins/avi_reader/libOpenDML/Index.h | 46 +++++ .../plugins/avi_reader/libOpenDML/Jamfile | 6 + .../avi_reader/libOpenDML/OpenDMLFile.cpp | 88 +++++----- .../avi_reader/libOpenDML/OpenDMLFile.h | 36 ++-- .../avi_reader/libOpenDML/OpenDMLIndex.cpp | 59 +++++++ .../avi_reader/libOpenDML/OpenDMLIndex.h | 42 +++++ .../avi_reader/libOpenDML/StandardIndex.cpp | 162 ++++++++++++++++++ .../avi_reader/libOpenDML/StandardIndex.h | 54 ++++++ 13 files changed, 594 insertions(+), 83 deletions(-) create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.h create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/Index.cpp create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/Index.h create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.cpp create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.h create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp create mode 100644 src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h diff --git a/src/add-ons/media/plugins/avi_reader/avi_reader.cpp b/src/add-ons/media/plugins/avi_reader/avi_reader.cpp index fbd1fb45d9..028cf8e18b 100644 --- a/src/add-ons/media/plugins/avi_reader/avi_reader.cpp +++ b/src/add-ons/media/plugins/avi_reader/avi_reader.cpp @@ -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; diff --git a/src/add-ons/media/plugins/avi_reader/avi_reader.h b/src/add-ons/media/plugins/avi_reader/avi_reader.h index db817cb521..15ce036562 100644 --- a/src/add-ons/media/plugins/avi_reader/avi_reader.h +++ b/src/add-ons/media/plugins/avi_reader/avi_reader.h @@ -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 { diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp new file mode 100644 index 0000000000..a962f839c7 --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.cpp @@ -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 +#include +#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; +} diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.h b/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.h new file mode 100644 index 0000000000..89ef8d7e9a --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/FallbackIndex.h @@ -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 diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/Index.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/Index.cpp new file mode 100644 index 0000000000..9880cd15fd --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/Index.cpp @@ -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 +#include +#include "Index.h" + +Index::Index(BPositionIO *source, OpenDMLParser *parser) + : fSource(source) + , fParser(parser) +{ +} + + +Index::~Index() +{ +} diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/Index.h b/src/add-ons/media/plugins/avi_reader/libOpenDML/Index.h new file mode 100644 index 0000000000..673cb6a4d4 --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/Index.h @@ -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 diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/Jamfile b/src/add-ons/media/plugins/avi_reader/libOpenDML/Jamfile index a3d4beac3b..31d4b805fe 100644 --- a/src/add-ons/media/plugins/avi_reader/libOpenDML/Jamfile +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/Jamfile @@ -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 ; diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.cpp index ed62a22057..f25d0b554e 100644 --- a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.cpp +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.cpp @@ -24,6 +24,9 @@ */ #include #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; } diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.h b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.h index 07ac7e022a..6970cb7af6 100644 --- a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.h +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLFile.h @@ -27,24 +27,25 @@ #include #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 diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.cpp new file mode 100644 index 0000000000..ab5a100666 --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.cpp @@ -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 +#include +#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; +} diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.h b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.h new file mode 100644 index 0000000000..77418287c8 --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/OpenDMLIndex.h @@ -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 diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp new file mode 100644 index 0000000000..79680ccec2 --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.cpp @@ -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 +#include +#include +#include +#include "ReaderPlugin.h" // B_MEDIA_* +#include "StandardIndex.h" +#include "OpenDMLParser.h" + +#include + + +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; +} + diff --git a/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h new file mode 100644 index 0000000000..878e55edfa --- /dev/null +++ b/src/add-ons/media/plugins/avi_reader/libOpenDML/StandardIndex.h @@ -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