blob: 8e00af8f87dd2e13f62dcd228c75dbea6eecb1d0 [file] [log] [blame]
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
//
// Defines two reader subclasses: MkvReaderQT and MkvBufferedReaderQT
// that can be passed to the mkvparser object for its use in reading WebM data.
// See www.webmproject.org for more info.
//
#ifndef MKVREADERQT_HPP_
#define MKVREADERQT_HPP_
#include <Carbon/Carbon.h>
#include <QuickTime/QuickTime.h>
#include <queue>
#include "mkvparser.hpp"
//
// MkvReaderQT
// Subclass of IMkvReader that knows about QuickTime dataRef and
// dataHandler objects, rather than plain file io.
//
class MkvReaderQT : public mkvparser::IMkvReader {
public:
// Patching the incomplete mkvparser::IMkvReader interface by making
// up our custom error codes, yay!
// These are used in Read() and Length() methods.
enum {
// Request completed successfully.
kSuccess = 0,
// Data handler not initialized or read request outside posible range.
kInvalidArgsOrState = -1,
// Some error occured while asking the data handler component to
// read some data.
kReadFailed = -2,
};
MkvReaderQT();
virtual ~MkvReaderQT();
// Finds and opens an appropriate data handler for the given data
// reference and queries its capabilities and optionally file
// size. Returns noErr on success, Mac/QuickTime error status otherwise.
virtual int Open(Handle dataRef, OSType dataRefType, bool query_size = true);
// Closes and releases the data handler component.
virtual void Close();
// IMkvReader interface - reads the requested amount of data,
// storing it in the passed |buffer|. Returns 0 on success.
virtual int Read(long long position, long length, unsigned char* buffer);
// IMkvReader interface - reports the total size of the file and the
// amount of data immediately available for reading. If the file
// size is unknown sets |total| to -1. Returns 0 on success.
virtual int Length(long long* total, long long* available);
// Returns true if the data is coming from a network stream.
bool is_streaming() const;
protected:
long long m_length;
DataHandler m_dataHandler; // ComponentInstance
// Is the data coming from network, as opposed to local disk?
bool is_streaming_;
private:
MkvReaderQT(const MkvReaderQT&);
MkvReaderQT& operator=(const MkvReaderQT&);
};
//
// MkvBufferedReaderQT
// Subclass of MkvReaderQT that uses async io to fill buffer.
//
class MkvBufferedReaderQT : public MkvReaderQT {
public:
// Status codes for RequestFillBuffer() method.
enum {
// The buffer can't fit more unread data.
kFillBufferNotEnoughSpace = 1,
};
static const long kReadBufferMaxSize = 4 * 1024 * 1024;
static const long kReadChunkSize = 32 * 1024;
static const long kMaxReadChunkSize = 1 * 1024 * 1024;
MkvBufferedReaderQT();
virtual ~MkvBufferedReaderQT();
// Finds and opens an appropriate data handler for the given data
// reference and queries its capabilities and optionally file
// size. Returns noErr on success, Mac/QuickTime error status otherwise.
virtual int Open(Handle dataRef, OSType dataRefType, bool query_size = true);
// Closes and releases the data handler component.
virtual void Close();
// IMkvReader interface - reads the requested amount of data,
// storing it in the passed |buffer|. Returns 0 on success.
virtual int Read(long long position, long length, unsigned char* buffer);
// IMkvReader interface - reports the total size of the file and the
// amount of data immediately available for reading. If the file
// size is unknown sets |total| to -1. Returns 0 on success.
virtual int Length(long long* total, long long* available);
// Requests an asynchronous read, of the given size, from the file
// into the internal buffer.
int RequestFillBuffer(long request_size);
// Requests an asynchronous from the file into the internal buffer.
// Will use default read size or one previously configured with
// set_chunk_size().
int RequestFillBuffer();
// Frees some already consumed data from the internal buffer.
void CompactBuffer(long requestedSize = 0);
// Gives the data handler some CPU time to handle the asynchronous requests.
void TaskDataHandler();
// Sets the read chunk size used by RequestFillBuffer().
long set_chunk_size(long chunk_size);
// Returns the current read chunk size.
long chunk_size() const;
// Returns true if a buffer fill request is pending.
bool RequestPending() const;
// Returns true if the end of data been reached?
bool eos() const;
// Callback handler for completed asynchronous read requests.
void ReadCompleted(Ptr request, OSErr read_error);
private:
MkvBufferedReaderQT(const MkvBufferedReaderQT&);
MkvBufferedReaderQT& operator=(const MkvBufferedReaderQT&);
// Size requested by RequestFillBuffer, nonzero if async read still
// outstanding.
long m_PendingReadSize;
OSErr readErr; // async read will set this
unsigned char buf[kReadBufferMaxSize];
long bufDataSize; // size of data in buf
long bufDataMax;
long bufStartFilePos; // long long
long bufCurFilePos;
long bufEndFilePos; // file position already read info buf so far
// Number of bytes to read at once.
long chunk_size_;
// Has the end of data been reached?
bool eos_;
DataHCompletionUPP read_completion_cb;
};
#endif // MKVREADERQT_HPP_