extern "C" { // Your addon should implement this function. // Return a new instance of your BMediaExtractorAddOn subclass. // This function will be called multiple times, and should return a // new instance each time. Return NULL if allocation fails. BMediaExtractorAddOn * instantiate_media_extractor_add_on(); } // Your add-on must implement a subclass of this class class BMediaExtractorAddOn { public: BMediaExtractorAddOn(void); virtual ~BMediaExtractorAddOn(void); //// stateless functions // these should work without dependency on a current stream /* begin BFileInterface functions */ // 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; /* begin transcoding functions */ // 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); /* end transcoding functions */ /* end BFileInterface functions */ /* begin BMediaAddOn functions */ // 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; /* begin transcoding function */ virtual status_t SniffOutputType(BMimeType & mimeType, float * outQuality); /* end transcoding function */ /* end BMediaAddOn functions */ // 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); /* begin transcoding function */ virtual status_t SniffOutputFormat(const media_file_format & format, float * outQuality); /* end transcoding function */ //// 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 BFile * source); virtual status_t SetSource(const entry_ref * source, int32 flags = 0); virtual status_t SetSource(const BDataIO * source); /* begin transcoding functions */ virtual status_t SetDestination(const BFile * source); virtual status_t SetDestination(const entry_ref * source, int32 flags = 0); virtual status_t SetDestination(const BDataIO * source); /* end transcoding functions */ //// 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); /* begin weird function that is missing but parallels add chunk */ // 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); /* end weird function that is missing but parallels add chunk */ // 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; } /* begin seek/sync functions for the extractor */ // 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; /* begin seek extensions functions */ // 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; /* end seek extensions functions */ // 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; /* end seek/sync functions for the extractor */ // 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: // use to negotiate the format for this track // straight BMediaTrack::DecodedFormat behavior virtual status_t NegotiateOutputFormat(BTrack * track, media_format * ioFormat) = 0; // get/set information about a particular track 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; } // 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; // read a chunk from this track only // straight BMediaTrack::ReadChunk behavior virtual status_t ReadChunk(BTrack * track, char ** outBuffer, int32 * ioSize, media_header * outHeader = NULL) = 0; // read frames from this track only // straight BMediaTrack::ReadChunk behavior virtual status_t ReadFrames(BTrack * track, void * outBuffer, int64 * outFrameCount, media_header * outHeader = NULL, media_decode_info * info = NULL) = 0; /* begin read extensions functions */ // read units of time from this track only virtual status_t ReadTime(BTrack * track, void * outBuffer, int64 * outTimeCount, media_header * outHeader = NULL, media_decode_info * info = NULL) = 0; // for completeness sake? // read a percentage from this track only virtual status_t Read(BTrack * track, void * outBuffer, int64 * outNumerator, media_header * outHeader = NULL, media_decode_info * info = NULL) = 0; /* end read extensions functions */ private: // this class is used by individual tracks // as a private interface to the extractor class BTrack { // use to negotiate the format for this track virtual status_t NegotiateOutputFormat(media_format * ioFormat) { return BExtractor::NegotiateOutputFormat(ioFormat); } // access to parameters for this track virtual status_t GetParameterValue(int32 id, const void * value, size_t * size) { 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); } // access to seek functionality on this track 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); } // access to readers for this track virtual status_t ReadChunk(char ** outBuffer, int32 * ioSize, media_header * outHeader = NULL) { return BExtractor::ReadChunk(this,outBuffer,ioSize,outHeader); } virtual status_t ReadFrames(void * outBuffer, int64 * outFrameCount, media_header * outHeader = NULL, media_decode_info * info = NULL) { return BExtractor::ReadFrames(this,outBuffer,outFrameCount,outHeader,info); } /* begin read extensions functions */ virtual status_t ReadTime(void * outBuffer, int64 * outTimeCount, media_header * outHeader = NULL, media_decode_info * info = NULL) { return BExtractor::ReadTime(this,outBuffer,outTimeCount,outHeader,info); } // for completeness sake? virtual status_t Read(void * outBuffer, int64 * outNumerator, media_header * outHeader = NULL, media_decode_info * info = NULL) { return BExtractor::Read(this,outBuffer,outNumerator,outHeader,info); } /* end read extensions functions */ // pad me }; // pad me };