[openbeosmediakit] new version of Extractor.h

  • From: "shatty" <shatty@xxxxxxxxxxxxx>
  • To: openbeosmediakit@xxxxxxxxxxxxx
  • Date: Sun, 01 Sep 2002 15:10:11 PDT

Hello all,

This version includes the BTrack inner class which provides the 
interface to the extractor functionality needed by the BMediaTrack 
object.  Please note that BTrack isn't complete yet, although the rest 
of the extractor API should be just about set.

Andrew Bachmann

=================================================

extern "C" {
  // Your addon should implement this function.
  // Return a new instance of your BExtractor subclass in outExtractor.
  // This function will be called multiple times.
  //
  // Return codes:
  // B_OK        : No error
  // B_NO_MEMORY : Storage for the extractor couldn't be allocated.
  status_t instantiate_extractor(BExtractor * outExtractor);
}

// necessary for a seek
// a reference point:
//    file start, current pos, file end
// a direction:
//    backwards, forwards
// a magnitude:
//    how far to go
// a resolution method:
//    prior key frame, following key frame, exact


enum media_seek_type {
    
    // seek to the closest keyframe that is after the given time/frame
        B_MEDIA_SEEK_CLOSEST_FORWARD = 1,  
    
    // seek to the closest keyframe that is before the given time/frame
        B_MEDIA_SEEK_CLOSEST_BACKWARD = 2,
        
        // ? internal usage? ? should be set to 7 now?
        B_MEDIA_SEEK_DIRECTION_MASK = 3,
        
#ifdef EXACT_SEEKING
    // seek as close to the time/frame as possible
    // This may involve seeking to a prior keyframe and then processing
    // the stream forward to the desired frame, for example.  When 
doing
    // this you should understand it may be expensive.
        B_MEDIA_SEEK_EXACTLY = 4,
#endif
};

// Required parameters
extern _IMPEXP_MEDIA const char * const B_DURATION; 
  // Output only: Selects the duration of the stream.
  //
  // This is the playing time of the stream, which may be
  // different from some or all of the durations for the
  // individual streams.  Return a negative number if the
  // duration is not a useful number. (like streaming audio)
  // This duration may be an estimate because determining
  // the exact duration may require parsing an entire file.
  // This duration may also be updated over time.  For
  // example, a file being read may also be being written to
  // by someone else.

extern _IMPEXP_MEDIA const char * const B_MEDIA_COPYRIGHT;
  // Output only: Selects the copyright notice of the stream.
  //
  // This is a string with a copyright notice.  The
  // string belongs to the extractor, so don't delete
  // or change it.

extern _IMPEXP_MEDIA const char * const B_TRACK_COUNT;
  // Output only: Selects the count of the
  // number of tracks in the stream.
  //
  // This is the current number of tracks in the stream.

#ifdef EXTRACTOR_SEEK
extern _IMPEXP_MEDIA const char * const B_SEEK_STREAM_NUMBER;
  // Input/Output: Selects the stream to be selected for seeking.
  //
  // When the extractor is asked to seek, it will seek on
  // this stream, and then seek the other streams depending
  // on where it ends up on the first stream.  A typical
  // value for this corresponds to a video stream.  In this
  // case the video stream will be seeked to the closest key
  // frame for example, and then any other streams will be
  // seeked to that time.  Only 'open' streams will be
  // seeked.
#endif

// Your addon must implement a subclass of this class
class BExtractor
{
public:
  BExtractor(void);
  virtual ~BExtractor(void);

  //// stateless functions
  // these should work without dependency on a current stream

#if FILE_INTERFACE
  // These are used to enumerate the set of file formats that this
  // extractor is prepared to read from.  Implementing these 
meaningfully
  // is important for discovering all types supported by the system.

  // Implement per BFileInterface::GetNextFileFormat
  //
  // Return codes:
  // B_OK : No error
  // B_ERROR : No more formats
  // GetNextInputFormat: required for BFileInterface functionality
  virtual status_t GetNextInputFormat(int32 * cookie,
                                      media_file_format * outFormat) = 
0;
  // Implement per BFileInterface::DisposeFileFormatCookie
  // DisposeInputFormatCookie: required for BFileInterface 
functionality
  virtual void DisposeInputFormatCookie(int32 cookie) = 0;

#if TRANSCODING
  // These are used to enumerate the set of file formats that this
  // extractor is prepared to transcode to.  The default implementation
  // simply returns no support.

  // Implement per BFileInterface::GetNextFileFormat
  //
  // Return codes:
  // B_OK : No error
  // B_ERROR : No more formats
  virtual status_t GetNextOutputFormat(int32 * cookie,
                                       media_file_format * outFormat);
  // Implement per BFileInterface::DisposeFileFormatCookie
  virtual void DisposeOutputFormatCookie(int32 cookie);
#endif
#endif
  
#ifdef MEDIA_ADD_ON
  // These are used to discover an extractors quality rating for a
  // particular media format.
  // Implement per BMediaAddOn::SniffType
  //
  // Return codes:
  // B_OK : No error
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle that mime type
  virtual status_t SniffInputType(BMimeType & mimeType, float * 
outQuality) = 0;
#ifdef TRANSCODING
  virtual status_t SniffOutputType(BMimeType & mimeType, float * 
outQuality);
#endif
#endif

  // Same as above, but for a media file format
  // The default implementation of this will iterate through your 
formats using
  // the appropriate interface from above, and simply return 0 for the 
quality
  // if it finds a matching supported format.
  //
  // Return codes:
  // B_OK : No error
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle that format
  virtual status_t SniffInputFormat(const media_file_format & format, 
float * outQuality);
#ifdef TRANSCODING
  virtual status_t SniffOutputFormat(const media_file_format & format, 
float * outQuality);
#endif

  //// state creation functions
  // calling these functions shouldn't affect the results of the 
stateless functions

  // Sets the current stream to source or destination
  // The default implementation for the BDataIO SetSource is to wrap
  // the BDataIO object in a buffer and call the BPositionIO SetSource.
  // The default implementation for the BFile SetSource is to send the
  // call directly to BPositionIO.  Note that it is highly recommended
  // to utilize the BNode properties of the BNodeIO/BFile object in
  // order to dynamically update your extractor state when the file
  // changes.  It is also recommended to use the BNode properties in
  // order to access the attributes of the source file; store or load
  // file specific extractor properties from here.
  // Note: the extractor is not require to return B_MEDIA_NO_HANDLER at
  // this point.  However, calling any stateful function after this
  // should return B_MEDIA_NO_HANDLER.
  //
  // Return codes:
  // B_OK : No error
  // B_NO_MEMORY : Storage for the buffer could not be allocated.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle that format
  virtual status_t SetSource(const BDataIO * source);
  virtual status_t SetSource(const BPositionIO * source) = 0;
  virtual status_t SetSource(const BDataIO * source);
  virtual status_t SetSource(const BFile * source);
#ifdef TRANSCODING
  virtual status_t SetDestination(const BDataIO * source);
  virtual status_t SetDestination(const BPositionIO * source);
  virtual status_t SetDestination(const BDataIO * source);
  virtual status_t SetDestination(const BFile * source);
#endif

  //// stateful functions
  // Calling these functions shouldn't affect the results of the 
stateless functions.
  // Calling these functions before calling a state creation function 
should return
  // B_NO_INIT.  Calling these functions after calling a state creation 
function with
  // an invalid argument should return B_MEDIA_NO_HANDLER.  Generally 
these
  // functions may also return any appropriate Storage Kit/File System 
Errors, such
  // as B_FILE_NOT_FOUND, B_BUSTED_PIPE, etc.

  // inspired by BMediaFile::GetFileFormatInfo
  //
  // Fills the specified media_file_format structure with
  // information describing the file format of the stream
  // currently referenced by the BEncoder.
  // 
  // Return codes:
  // B_OK        : No error
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_NO_MEMORY : Storage for part of the media_file_format
  //               object couldn't be allocated.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t GetFileFormatInfo(media_file_format * mfi) = 0;
                             
  // The extractor should implement this function in the
  // manner described for BFileInterface::SniffRef, except that
  // it uses the current Source instead of an entry_ref
  //
  // Return codes:
  // B_OK : No error
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t Sniff(char * outMimeType, float * outQuality) = 0;

  // implement per BMediaTrack::AddChunk(void)
  // 
  // Return codes:
  // B_OK        : No error
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t WriteChunk(int32 type,
                              const void * data,
                              size_t size);

#ifdef IT_IS_WEIRD_THIS_IS_MISSING_BUT_ADD_CHUNK_IS_UGLY_ANYWAY
  // implement per BMediaTrack::ReadChunk(void) <- missing????
  // umm.. has the same semantics as AddChunk, yeah that's it...
  // 
  // Return codes:
  // B_OK        : No error
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t ReadChunk(int32 * outType,
                             const void * outData,
                             size_t * outSize);
#endif

  // The extractor should do any cleanup required.  After
  // this function returns, the source object should be
  // closed and deleted by the caller, not by Close().
  // The default implementation simply returns B_OK.
  //
  // Return codes:
  // B_OK : No error
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t Close(void);

  //// shared state functions
  // The ParameterWeb interface is used to publish both file specific
  // and extractor specific options.  Accessing a file specific 
parameter
  // before calling a state creation function should return B_NO_INIT.
  // Accessing a file parameter after calling a state creation function
  // with an invalid argument should return B_MEDIA_NO_HANDLER.  
Accessing
  // extractor specific options should never return these errors, but 
may
  // return other errors.

  // the extractor should provide several basic parameters
  // through this interface, such as B_TRACK_COUNT, and B_DURATION
  // see also BMediaFile::GetParameterValue
  // hmmm... how to pick which stream parameters apply to?
  // could use a bitwise or with B_OUTPUT_STREAM (and a
  // B_INPUT_STREAM for completeness)
  //
  // Return codes:
  // B_OK : No error
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t GetParameterValue(int32 id, const void * value, 
                                     size_t * size) = 0;

  // the extractor may optionally supply parameters for the
  // user to configure, such as buffering information(?)
  // see also BMediaFile::SetParameterValue
  //
  // Return codes:
  // B_OK : No error
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t SetParameterValue(int32 id, const void * value,
                                     size_t size);

  // The extractor may return a BParameterWeb for browsing or
  // configuring the extractor's parameters.  Returns NULL if the
  // extractor doesn't support this.  The default implementation
  // simply returns NULL.  Note: if the Source is not in a good
  // state, this web may not include file specific parameters.
  //
  // As a suggestion you should use groups to gather parameters
  // related to the encoder and separate them from parameters
  // related to the input stream and output stream (if applicable)
  //  
  // See also BMediaFile::Web
  virtual BParameterWeb * Web(void) { return NULL; }

  // The extractor may return a BView for browsing or configuring
  // the extractor's parameters.  Returns NULL if the extractor
  // doesn't support this.  The default implementation simply
  // returns NULL.
  virtual BView * GetParameterView(void) (void) { return NULL; }

#ifdef EXTRACTOR_SEEK
  // The extractor will seek first on the seek track, just like
  // BMediaTrack::SeekToTime.  Like SeekToTime, it accepts a flag
  // argument which tells how to find the nearest acceptable frame.
  // After finding this frame, it will also seek any other open
  // streams in an extractor-dependent fashion.  Usually the seek
  // stream will be a video stream.  If seeked to a keyframe, for
  // example, the audio stream will be seeked to an appropriate time.
  //
  // This may be more efficient than seeking the seek track through
  // the BMediaTrack interface, and then calling Sync() here.  It
  // should not be less efficient.
  //
  // See also BMediaTrack::SeekToTime
  // see above for additions to media_seek_type (used for flags)
  // seekMode per BFile::Seek, only SEEK_SET is required
  //
  // Return codes:
  // B_OK : No error
  // B_UNSUPPORTED : This extractor does not support general seeking
  //                 for this stream.
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t SeekToTime(bigtime_t * ioTime,
                              int32 mediaSeekFlags = 0,
                              int32 seekMode = 0) = 0;
  
  // The extractor will seek first on the seek track, just like
  // BMediaTrack::SeekToFrame.  Like SeekToFrame, it accepts a flag
  // argument which tells how to find the nearest acceptable frame.
  // After finding this frame, it will also seek any other open
  // streams in an extractor-dependent fashion.  Usually the seek
  // stream will be a video stream.  If seeked to a keyframe, for
  // example, the audio stream will be seeked to an appropriate time.
  //
  // This may be more efficient than seeking the seek track through
  // the BMediaTrack interface, and then calling Sync() here.  It
  // should not be less efficient.
  //
  // See also BMediaTrack::SeekToFrame
  // see above for additions to media_seek_type (used for flags)
  // seekMode per BFile::Seek, only SEEK_SET is required
  //
  // Return codes:
  // B_OK : No error
  // B_UNSUPPORTED : This extractor does not support general seeking
  //                 for this stream.
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t SeekToFrame(int64 * ioFrame,
                               int32 mediaSeekFlags = 0,
                               int32 seekMode = 0) = 0;

#ifdef SEEK_EXTENSIONS
  // The extractor will seek first on the seek track.  It goes to
  // a position defined by ioChunk*chunkSize, where chunkSize is
  // defined by the decoder.  For example, some streams are not byte
  // streams, but rather bitstreams.  In this case the chunkSize may
  // correspond to 1 bit.  Like the other MediaTrack Seeks, it
  // accepts a flag argument which tells how to find the nearest
  // acceptable frame.
  // After finding this frame, it will also seek any other open
  // streams in an extractor-dependent fashion.  Usually the seek
  // stream will be a video stream.  If seeked to a keyframe, for
  // example, the audio stream will be seeked to an appropriate time.
  //
  // This may be more efficient than seeking the seek track through
  // the BMediaTrack interface, and then calling Sync() here.  It
  // should not be less efficient.
  //
  // see above for additions to media_seek_type (used for flags)
  // seekMode per BFile::Seek, only SEEK_SET is required
  //
  // Return codes:
  // B_OK : No error
  // B_UNSUPPORTED : This extractor does not support general seeking
  //                 for this stream.
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t SeekToChunk(int64 * ioChunk,
                               int32 mediaSeekFlags = 0,
                               int32 seekMode = 0) = 0;
  
  // The extractor will seek first on the seek track.  It goes to a
  // position defined by numerator/(duration of this file).  For
  // example: Seek(LONG_LONG_MAX/2) would seek halfway through the
  // stream.  Like the other MediaTrack Seeks, it accepts a flag
  // argument which tells how to find the nearest acceptable frame.
  // If the seekMode is SEEK_SET it will seek a fraction of the way
  // back to the beginning from the current location.  If the seekMode
  // is SEEK_END it will seek a fraction of the way to the end from
  // the current location.  If the seekMode is SEEK_CUR it will seek
  // as above. (fraction of the entire file duration)
  // After finding this frame, it will also seek any other open
  // streams in an extractor-dependent fashion.  Usually the seek
  // stream will be a video stream.  If seeked to a keyframe, for
  // example, the audio stream will be seeked to an appropriate time.
  //
  // This may be a lot more efficient than seeking to a time or frame
  // for some streams. (in particular, nonindexed streams)
  //
  // This may be more efficient than seeking the seek track through
  // the BMediaTrack interface, and then calling Sync() here.  It
  // should not be less efficient.
  //
  // Note: because the duration may change over time (if the file is
  // being written to, for example) the result of seeking with a
  // particular numerator may also change.  It will usually be later,
  // but could also be earlier.
  //
  // see above for additions to media_seek_type (used for flags)
  // seekMode per BFile::Seek, only SEEK_CUR is required
  //
  // Return codes:
  // B_OK : No error
  // B_UNSUPPORTED : This extractor does not support general seeking
  //                 for this stream.
  // B_NO_INIT     : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t Seek(int64 * numerator,
                        int32 mediaSeekFlags = 0,
                        int32 seekMode = 0) = 0;
#endif

  // Using the location from the seek stream, seeks any other open
  // streams in an extractor-dependent fashion.  Usually the seek
  // stream will be a video stream.  If seeked to a keyframe, for
  // example, the audio stream will be seeked to an appropriate time.
  //
  // Note: if not supplied, the seek stream will be the current one
  // as retrieved by GetParameterValue, not zero.  Sync() will do
  // this check for you.
  //
  // Return codes:
  // B_OK : No error
  // B_UNSUPPORTED : This extractor does not support general syncing
  //                 for this stream.
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual status_t Sync(int32 seekStream = 0) = 0;
#endif
  
  // Returns a thing that is useful for MediaTrack to do its business.
  //
  // May simply include state but will probably include a pointer back
  // to this object, and will likely call functions that are defined by
  // subclasses of this extractor.  For example, the subclass may 
define
  // a function like this:
  // SeekTrackToFrame(BTrack * track, int64 ioFrame, int32 flags = 0) {
  // ... }
  // and then when SeekToFrame is called on the BTrack object the work
  // would be done by the Extractor.
  //
  // Also, any track extracted using this function will be seeked by
  // the extractor seek functions.  Any track not extracted by this
  // function will not be seeked.  If the seekMode parameter is
  // supplied as SEEK_CUR the track will be seeked before being
  // returned, as per Sync().  However because this involves only
  // one track it may be more efficient than retrieving the track and
  // then calling Sync();  If seekMode is SEEK_SET then the current
  // seek time for the track will be no later than the earliest
  // seekable time.  If seekMode is SEEK_END the current seek time
  // for the track will be no earlier than the earliest seekable time.
  // Note: for non-seekable tracks, this may may no difference.
  // The default for seekMode is SEEK_SET.
  //
  // If the seek parameter is passed as false, no pre-seeking will be
  // performed on the track.  The current seek time may be arbitrary
  // or even illegal.  Attempting to decode data from the track in
  // this state will result in an error if the state is illegal.
  //
  // Return codes:
  // B_OK : No error
  // B_STREAM_NOT_FOUND
  // B_BAD_INDEX : The index supplied does not correspond to a valid
  //               track in this stream.
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  virtual BTrack * TrackAt(int32 index, int32 seekMode = 0,
                                        bool seek = true) = 0;
  
  // Disclaims interest in a particular track.  After releasing a
  // track the track will no longer be seeked by the extractor.
  //
  // Return codes:
  // B_OK : No error
  // B_BAD_TYPE  : This track does not correspond to this extractor.
  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
  status_t ReleaseTrack(BTrack * track);

protected:
  // seek only this particular track to the given time
  // straight BMediaTrack::SeekToTime behavior
  virtual status_t SeekToTime(BTrack * track,
                              bigtime_t * ioTime,
                              int32 mediaSeekFlags = 0,
                              int32 seekMode = 0) = 0;
  // seek only this particular track to the given frame
  // straight BMediaTrack::SeekToFrame behavior
  virtual status_t SeekToFrame(BTrack * track,
                               int64 * ioFrame,
                               int32 mediaSeekFlags = 0,
                               int32 seekMode = 0) = 0;
  // seek only this particular track to the given chunk
  // straight BMediaTrack::SeekToChunk behavior
  virtual status_t SeekToChunk(BTrack * track,
                               int64 * ioChunk,
                               int32 mediaSeekFlags = 0,
                               int32 seekMode = 0) = 0;
  // seek only this particular track to the given chunk
  // straight BMediaTrack::Seek behavior
  virtual status_t Seek(BTrack * track,
                        int64 * numerator,
                        int32 mediaSeekFlags = 0,
                        int32 seekMode = 0) = 0;

    virtual status_t GetParameterValue(BTrack * track, int32 id,
                                       const void * value, size_t * 
size) = 0;
    virtual status_t SetParameterValue(BTrack * track, int32 id,
                                       const void * value, size_t 
size);
    virtual BParameterWeb * Web(BTrack * track) { return NULL; }
    virtual BView * GetParameterView(BTrack * track) { return NULL; }

private:
  // this class is used by individual tracks
  // as a private interface to the extractor
  class BTrack {
    virtual status_t SeekToTime(bigtime_t * ioTime,
                              int32 mediaSeekFlags = 0,
                              int32 seekMode = 0) {
      return 
BExtractor::SeekToTime(this,ioTime,mediaSeekFlags,seekMode);
    }
    virtual status_t SeekToFrame(int64 * ioFrame,
                                 int32 mediaSeekFlags = 0,
                                 int32 seekMode = 0) {
      return 
BExtractor::SeekToFrame(this,ioFrame,mediaSeekFlags,seekMode);
    }
    virtual status_t SeekToChunk(int64 * ioChunk,
                                 int32 mediaSeekFlags = 0,
                                 int32 seekMode = 0) {
      return 
BExtractor::SeekToChunk(this,ioChunk,mediaSeekFlags,seekMode);
    }
    virtual status_t Seek(int64 * numerator,
                          int32 mediaSeekFlags = 0,
                          int32 seekMode = 0) {
      return BExtractor::Seek(this,numerator,mediaSeekFlags,seekMode);
    }
    
    virtual status_t GetParameterValue(int32 id, const void * value, 
                                       size_t * size) = 0 {
      return BExtractor::GetParameterValue(this,id,value,size);
    }
    virtual status_t SetParameterValue(int32 id, const void * value,
                                       size_t size) {
      return BExtractor::SetParameterValue(this,id,value,size);
    }
    virtual BParameterWeb * Web(void) {
      return BExtractor::Web(this);
    }
    virtual BView * GetParameterView(void) {
      return BExtractor::GetParameterView(this);
    }

    // pad me
  };
  
  // pad me
};



Other related posts: