media_kit: Move some files and headers under docs/develop/media

This commit is contained in:
Dario Casalinuovo
2017-01-16 22:53:44 +01:00
parent edbb68258b
commit 41acdd1d90
5 changed files with 0 additions and 0 deletions
+560
View File
@@ -0,0 +1,560 @@
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
};
+241
View File
@@ -0,0 +1,241 @@
// A MediaFileProducer is a node that
// implements FileInterface and BBufferProducer.
// it produces one output, a multistream
#if !defined(_MEDIA_FILE_PRODUCER_H)
#define _MEDIA_FILE_PRODUCER_H
#include <MediaDefs.h>
#include <MediaNode.h>
#include <FileInterface.h>
#include <BufferProducer.h>
class MediaFileProducer :
public BFileInterface,
public BBufferProducer
{
protected:
MediaFileProducer();
virtual ~MediaFileProducer();
/*************************/
/* begin from BMediaNode */
public:
/* this port is what a media node listens to for commands */
virtual port_id ControlPort() const;
virtual BMediaAddOn* AddOn(
int32 * internal_id) const = 0; /* Who instantiated you -- or NULL for app class */
protected:
/* These don't return errors; instead, they use the global error condition reporter. */
/* A node is required to have a queue of at least one pending command (plus TimeWarp) */
/* and is recommended to allow for at least one pending command of each type. */
/* Allowing an arbitrary number of outstanding commands might be nice, but apps */
/* cannot depend on that happening. */
virtual void Start(
bigtime_t performance_time);
virtual void Stop(
bigtime_t performance_time,
bool immediate);
virtual void Seek(
bigtime_t media_time,
bigtime_t performance_time);
virtual void SetRunMode(
run_mode mode);
virtual void TimeWarp(
bigtime_t at_real_time,
bigtime_t to_performance_time);
virtual void Preroll();
virtual void SetTimeSource(
BTimeSource * time_source);
public:
virtual status_t HandleMessage(
int32 message,
const void * data,
size_t size);
protected:
/* Called when requests have completed, or failed. */
virtual status_t RequestCompleted( /* reserved 0 */
const media_request_info & info);
protected:
virtual status_t DeleteHook(BMediaNode * node); /* reserved 1 */
virtual void NodeRegistered(); /* reserved 2 */
public:
/* fill out your attributes in the provided array, returning however many you have. */
virtual status_t GetNodeAttributes( /* reserved 3 */
media_node_attribute * outAttributes,
size_t inMaxCount);
virtual status_t AddTimer(
bigtime_t at_performance_time,
int32 cookie);
/* end from BMediaNode */
/***********************/
/*****************************/
/* begin from BFileInterface */
protected:
//included from BMediaNode
//virtual status_t HandleMessage(
// int32 message,
// const void * data,
// size_t size);
virtual status_t GetNextFileFormat(
int32 * cookie,
media_file_format * out_format) = 0;
virtual void DisposeFileFormatCookie(
int32 cookie) = 0;
virtual status_t GetDuration(
bigtime_t * out_time) = 0;
virtual status_t SniffRef(
const entry_ref & file,
char * out_mime_type, /* 256 bytes */
float * out_quality) = 0;
virtual status_t SetRef(
const entry_ref & file,
bool create,
bigtime_t * out_time) = 0;
virtual status_t GetRef(
entry_ref * out_ref,
char * out_mime_type) = 0;
/* end from BFileInterface */
/***************************/
/******************************/
/* begin from BBufferProducer */
protected:
/* functionality of BBufferProducer */
virtual status_t FormatSuggestionRequested(
media_type type,
int32 quality,
media_format * format) = 0;
virtual status_t FormatProposal(
const media_source & output,
media_format * format) = 0;
/* If the format isn't good, put a good format into *io_format and return error */
/* If format has wildcard, specialize to what you can do (and change). */
/* If you can change the format, return OK. */
/* The request comes from your destination sychronously, so you cannot ask it */
/* whether it likes it -- you should assume it will since it asked. */
virtual status_t FormatChangeRequested(
const media_source & source,
const media_destination & destination,
media_format * io_format,
int32 * _deprecated_) = 0;
virtual status_t GetNextOutput( /* cookie starts as 0 */
int32 * cookie,
media_output * out_output) = 0;
virtual status_t DisposeOutputCookie(
int32 cookie) = 0;
/* In this function, you should either pass on the group to your upstream guy, */
/* or delete your current group and hang on to this group. Deleting the previous */
/* group (unless you passed it on with the reclaim flag set to false) is very */
/* important, else you will 1) leak memory and 2) block someone who may want */
/* to reclaim the buffers living in that group. */
virtual status_t SetBufferGroup(
const media_source & for_source,
BBufferGroup * group) = 0;
/* Format of clipping is (as int16-s): <from line> <npairs> <startclip> <endclip>. */
/* Repeat for each line where the clipping is different from the previous line. */
/* If <npairs> is negative, use the data from line -<npairs> (there are 0 pairs after */
/* a negative <npairs>. Yes, we only support 32k*32k frame buffers for clipping. */
/* Any non-0 field of 'display' means that that field changed, and if you don't support */
/* that change, you should return an error and ignore the request. Note that the buffer */
/* offset values do not have wildcards; 0 (or -1, or whatever) are real values and must */
/* be adhered to. */
virtual status_t VideoClippingChanged(
const media_source & for_source,
int16 num_shorts,
int16 * clip_data,
const media_video_display_info & display,
int32 * _deprecated_);
/* Iterates over all outputs and maxes the latency found */
virtual status_t GetLatency(
bigtime_t * out_lantency);
virtual status_t PrepareToConnect(
const media_source & what,
const media_destination & where,
media_format * format,
media_source * out_source,
char * out_name) = 0;
virtual void Connect(
status_t error,
const media_source & source,
const media_destination & destination,
const media_format & format,
char * io_name) = 0;
virtual void Disconnect(
const media_source & what,
const media_destination & where) = 0;
virtual void LateNoticeReceived(
const media_source & what,
bigtime_t how_much,
bigtime_t performance_time) = 0;
virtual void EnableOutput(
const media_source & what,
bool enabled,
int32 * _deprecated_) = 0;
virtual status_t SetPlayRate(
int32 numer,
int32 denom);
virtual status_t HandleMessage( /* call this from the thread that listens to the port */
int32 message,
const void * data,
size_t size);
virtual void AdditionalBufferRequested( // used to be Reserved 0
const media_source & source,
media_buffer_id prev_buffer,
bigtime_t prev_time,
const media_seek_tag * prev_tag); // may be NULL
virtual void LatencyChanged( // used to be Reserved 1
const media_source & source,
const media_destination & destination,
bigtime_t new_latency,
uint32 flags);
/* end from BBufferProducer */
/****************************/
private:
MediaFileProducer( /* private unimplemented */
const MediaFileProducer & clone);
MediaFileProducer & operator=(
const MediaFileProducer & clone);
/* Mmmh, stuffing! */
virtual status_t _Reserved_MediaFileProducer_0(void *);
virtual status_t _Reserved_MediaFileProducer_1(void *);
virtual status_t _Reserved_MediaFileProducer_2(void *);
virtual status_t _Reserved_MediaFileProducer_3(void *);
virtual status_t _Reserved_MediaFileProducer_4(void *);
virtual status_t _Reserved_MediaFileProducer_5(void *);
virtual status_t _Reserved_MediaFileProducer_6(void *);
virtual status_t _Reserved_MediaFileProducer_7(void *);
virtual status_t _Reserved_MediaFileProducer_8(void *);
virtual status_t _Reserved_MediaFileProducer_9(void *);
virtual status_t _Reserved_MediaFileProducer_10(void *);
virtual status_t _Reserved_MediaFileProducer_11(void *);
virtual status_t _Reserved_MediaFileProducer_12(void *);
virtual status_t _Reserved_MediaFileProducer_13(void *);
virtual status_t _Reserved_MediaFileProducer_14(void *);
virtual status_t _Reserved_MediaFileProducer_15(void *);
uint32 _reserved_media_file_node_[16];
};
#endif /* _MEDIA_FILE_PRODUCER_H */
+104
View File
@@ -0,0 +1,104 @@
// A MediaFileProducerAddOn is an add-on
// that can make MediaFileProducer nodes
#if !defined(_MEDIA_FILE_PRODUCER_ADD_ON_H)
#define _MEDIA_FILE_PRODUCER_ADD_ON_H
#include <MediaDefs.h>
#include <MediaAddOn.h>
class MediaFileProducerAddOn :
public BMediaAddOn
{
public:
MediaFileProducerAddOn();
virtual ~MediaFileProducerAddOn();
/**************************/
/* begin from BMediaAddOn */
public:
virtual ~BMediaAddOn();
virtual status_t InitCheck(
const char ** out_failure_text);
virtual int32 CountFlavors();
virtual status_t GetFlavorAt(
int32 n,
const flavor_info ** out_info);
virtual BMediaNode * InstantiateNodeFor(
const flavor_info * info,
BMessage * config,
status_t * out_error);
virtual status_t GetConfigurationFor(
BMediaNode * your_node,
BMessage * into_message);
virtual bool WantsAutoStart();
virtual status_t AutoStart(
int in_count,
BMediaNode ** out_node,
int32 * out_internal_id,
bool * out_has_more);
/* only implement if you have a B_FILE_INTERFACE node */
virtual status_t SniffRef(
const entry_ref & file,
BMimeType * io_mime_type,
float * out_quality,
int32 * out_internal_id);
virtual status_t SniffType( // This is broken if you deal with producers
const BMimeType & type, // and consumers both. Use SniffTypeKind instead.
float * out_quality, // If you implement SniffTypeKind, this doesn't
int32 * out_internal_id); // get called.
virtual status_t GetFileFormatList(
int32 flavor_id, // for this node flavor (if it matters)
media_file_format * out_writable_formats, // don't write here if NULL
int32 in_write_items, // this many slots in out_writable_formats
int32 * out_write_items, // set this to actual # available, even if bigger than in count
media_file_format * out_readable_formats, // don't write here if NULL
int32 in_read_items, // this many slots in out_readable_formats
int32 * out_read_items, // set this to actual # available, even if bigger than in count
void * _reserved); // ignore until further notice
virtual status_t SniffTypeKind( // Like SniffType, but for the specific kind(s)
const BMimeType & type,
uint64 in_kinds,
float * out_quality,
int32 * out_internal_id,
void * _reserved);
/* end from BMediaAddOn */
/************************/
private:
MediaFileProducerAddOn( /* private unimplemented */
const MediaFileProducerAddOn & clone);
MediaFileProducerAddOn & operator=(
const MediaFileProducerAddOn & clone);
/* Mmmh, stuffing! */
virtual status_t _Reserved_MediaFileProducerAddOn_0(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_1(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_2(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_3(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_4(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_5(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_6(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_7(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_8(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_9(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_10(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_11(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_12(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_13(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_14(void *);
virtual status_t _Reserved_MediaFileProducerAddOn_15(void *);
uint32 _reserved_media_file_node_[16];
};
#if BUILDING_MEDIA_FILE_PRODUCER__ADD_ON
extern "C" _EXPORT BMediaAddOn * make_media_file_producer_add_on(image_id you);
#endif
#endif /* _MEDIA_FILE_PRODUCER_ADD_ON_H */
+78
View File
@@ -0,0 +1,78 @@
This file contains extensions to the standard set of parameter web constants.
/* constants for extractors */
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_MEDIA_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.
extern _IMPEXP_MEDIA const char * const B_MEDIA_FRAME_COUNT;
// Output only: Selects the count of the
// number of frames in the stream.
//
// This is the current number of frames in the stream.
// See BMediaTrack::CountFrames()
extern _IMPEXP_MEDIA const char * const B_MEDIA_CURRENT_FRAME_INDEX;
// Output only: Selects the index of the
// current frame in the stream.
//
// This is the current frame in the stream.
// See BMediaTrack::CurrentFrame()
extern _IMPEXP_MEDIA const char * const B_MEDIA_CURRENT_TIME;
// Output only: Selects the current time of the stream.
//
// This is the time at the current position of the stream.
// See BMediaTrack::CurrentTime()
extern _IMPEXP_MEDIA const char * const B_MEDIA_ENCODED_FORMAT;
// Output only: Selects the native encoded format of the streams data.
//
// See BMediaTrack::EncodedFormat()
extern _IMPEXP_MEDIA const char * const B_MEDIA_TRACK_CODEC_INFO;
// Output only: Selects the codec information for this stream
//
// See BMediaTrack::GetCodecInfo()
extern _IMPEXP_MEDIA const char * const B_MEDIA_QUALITY;
// Input/output: Selects the quality rating for this stream
//
// See BMediaTrack::GetQuality and BMediaTrack::SetQuality
// Used for extractor-based seek:
extern _IMPEXP_MEDIA const char * const B_MEDIA_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.
+160
View File
@@ -0,0 +1,160 @@
This is the current media_seek_type from MediaTrack.h:
enum media_seek_type {
B_MEDIA_SEEK_CLOSEST_FORWARD = 1,
B_MEDIA_SEEK_CLOSEST_BACKWARD = 2,
B_MEDIA_SEEK_DIRECTION_MASK = 3
};
It is used as an argument to these BMediaTrack functions:
status_t SeekToFrame(int64 *ioFrame, int32 flags = 0)
status_t SeekToTime(bigtime_t *ioTime, int32 flags = 0)
Those int32 should be changed to media_seek_type?
============================
Here are some aspects of seeking:
A. Where are you seeking from?
1. the start of the file
Currently is done always now.
2. the current position
Suggested for streams, or other situations where you might lose track of your position.
3. the end of the file
Suggested for completeness.
B. Which direction are you seeking in?
1. backwards
This is most useful for A2, A3.
If you seek to before the beginning of the stream you could reasonably wait until enough time elapsed that you should be at the start of the stream, and then begin playing the beginning of the stream.
2. forwards
This is most useful for A1, A2.
If you seek past the end of the stream you can only hope that you receive data on the stream faster than time elapses. At that point you could begin playing.
C. How far are you seeking?
1. specify by time
Currently supported via SeekToTime
2. specify by frame
Currently supported via SeekToFrame
3. specify by chunk
Suggested for completeness. This may prevent someone from having to loop over ReadChunk in order to get to a position.
4. specify by percentage
Suggested for efficiency. For applications such as players which do not require precise time/frame based seeking, this may allow fast seeking. (especially for nonindexed tracks) After seeking like this absolute time/frame information maybe not be available.
------------
D. What constitutes a usable position?
0. track's discretion
1. a frame that can be decoded in 1 step
Currently supported by most tracks AFAIK.
2. a frame that can be decoded in multiple steps
Suggested to allow exact but slow searching.
3. any frame
Suggested to allow very fast searching.
E. What should the track do if you specified a position that is not usable?
0. track's discretion
Currently supported by supplying no seek flags.
1. go backward until you reach a usable position
Currently supported by supplying B_MEDIA_SEEK_CLOSEST_BACKWARD as a seek flag.
2. go forward until you reach a usable position
Currently supported by supplying B_MEDIA_SEEK_CLOSEST_FORWARD as a seek flag.
3. go whichever direction has the nearest usable position
Suggested to get as close to the specified time/frame as possible.
F. What state should the decoder for this track be left in?
1. whatever state it was in before
Not recommended. May even not be possible since the decoder's help may be required for seeking.
2. track's discretion
Suggested for efficiency.
3. prepared to return a correct, decoded frame
Currently supported by supplying no seek flags.
4. prepared to return meaningless frames until a usable position is reached
Not recommended: doubtful anyone would want to supply such a flag.
Only meaningful in conjunction with D3.
5. prepared to return empty frames until a usable position is reached
Not recommended. Requires some meaningful "empty" frame to be supplied: probably from the decoder. For video this would probably be a black colored frame (in whatever colorspace you are in). For audio this would probably be silence. Advantage: no work for app. Disadvantages: work for decoder, no way for app to know that this isn't the "real" frame.
6. prepared to return non-frames until a usable position is reached
Suggested for efficiency. Requires some sort of flag to be returned. Could be implemented by a status_t (B_EMPTY_FRAME or B_EMPTY_FRAMES) which would be returned from a subsequent call to ReadFrames()
Only meaningful in conjunction with D3.
G. How much information must be reliable after the seek?
1. the current frame
2. the current time
3. the current percentage
4. the current chunk
5. track's discretion
"<marcus_o> B_MEDIA_SEEK_LAZY -> resulting seek is inaccourate, timing information might be wrong after doing it, but it's very fast way to seek in files
<marcus_o> used for display purposes, when you want to seek to about 85% of a MPEG video or something similar"
H. What should be done about other tracks that are also from the same source as this track?
1. do nothing
Currently supported by suppling no seek flags.
2. seek the open tracks to whatever time this track ends up at
Suggested for convenience, efficiency. The track would seek itself first and then seek the other open tracks to the resulting position.
3. seek all other tracks to whatever time this track ends up at
Not recommended: may be uselessly costly if there are a lot of nonopen tracks.
4. seek the open tracks to the same time
Not recommended: this is just asking for trouble and if someone wants to do this then can simply loop over all the tracks.
5. seek all other tracks to the same time
Not recommended: this is just asking for trouble and maybe very costly if there are a lot of nonopen tracks
"<marcus_o> B_MEDIA_SEEK_ALL_TRACKS -> seeks all tracks (audio and video) that belong to the file that this track belongs to
<marcus_o> makes sure you can seek a file without introducing loss of sync betewwn audio/video/subtitles, whatever"
============================
Andrew Bachmann's proposal:
A: provide all by another parameter on each seek function. use the posix SEEK_SET, SEEK_CUR, SEEK_END
B: use the sign of the first parameter (+=forward, -=backward)
C: provide all by adding two new functions:
SeekToChunk(int64 * ioChunk, media_seek_type flags)
same as calling ReadChunk for ioChunk times. not sure the flags are necessary.
SeekToPercentage(int64 * ioNumerator, media_seek_type flags)
similar to SeekToTime(Duration()*(ioNumerator/MAX_INT64),flags) or
SeekToFrame(CountFrames()*(ioNumerator/MAX_INT64),flags) but
possibly much more efficient
D: provide all by using new seek bits
supplying no bits is the same as supplying all bits (ANY)
ANY = IMMEDIATE | SLOW | IGNORE
B_MEDIA_SEEK_DECODABILITY_ANY (per D0)
B_MEDIA_SEEK_DECODABILITY_IMMEDIATE (per D1)
B_MEDIA_SEEK_DECODABILITY_SLOW (per D2)
B_MEDIA_SEEK_DECODABILITY_IGNORE (per D3)
E: provide all by using the existing seek bits + new bit
supplying no bits is the same as suppling all bits (ANY)
ANY = BACKWARD | FORWARD | NEAREST
B_MEDIA_SEEK_DIRECTION_ANY (per E0)
B_MEDIA_SEEK_CLOSEST_BACKWARD (per E1)
B_MEDIA_SEEK_CLOSEST_FORWARD (per E2)
B_MEDIA_SEEK_DIRECTION_NEAREST (per E3)
F: support F3 and F6
if B_MEDIA_SEEK_DECODABILITY_IMMEDIATE or B_MEDIA_SEEK_DECODABILITY_SLOW
then the decoder should be ready. (we want meaningful frames)
if B_MEDIA_SEEK_DECODABILITY_IGNORE
then if the decoder is not ready
ReadFrames() will return B_EMPTY_FRAMES until it is ready.
G: provide all by using new seek bits
supplying no bits means is the same as suppling NOTHING
ALL = FRAME | TIME | PERCENTAGE | CHUNK
B_MEDIA_SEEK_CURRENT_NOTHING
B_MEDIA_SEEK_CURRENT_FRAME (H1)
B_MEDIA_SEEK_CURRENT_TIME (H2)
B_MEDIA_SEEK_CURRENT_PERCENTAGE (H3)
B_MEDIA_SEEK_CURRENT_CHUNK (H4)
B_MEDIA_SEEK_CURRENT_ALL
H: support H1 and H2 by using a new seek bit
supplying no bits means don't seek open tracks
B_MEDIA_SEEK_SYNC_OPEN_TRACKS (per G2)