1extern "C" {
2  // Your addon should implement this function.
3  // Return a new instance of your BMediaExtractorAddOn subclass.
4  // This function will be called multiple times, and should return a
5  // new instance each time.  Return NULL if allocation fails.
6  BMediaExtractorAddOn * instantiate_media_extractor_add_on();
7}
8
9// Your add-on must implement a subclass of this class
10class BMediaExtractorAddOn
11{
12public:
13  BMediaExtractorAddOn(void);
14  virtual ~BMediaExtractorAddOn(void);
15
16  //// stateless functions
17  // these should work without dependency on a current stream
18
19/* begin BFileInterface functions */
20  // These are used to enumerate the set of file formats that this
21  // extractor is prepared to read from.  Implementing these meaningfully
22  // is important for discovering all types supported by the system.
23
24  // Implement per BFileInterface::GetNextFileFormat
25  //
26  // Return codes:
27  // B_OK : No error
28  // B_ERROR : No more formats
29  // GetNextInputFormat: required for BFileInterface functionality
30  virtual status_t GetNextInputFormat(int32 * cookie,
31                                      media_file_format * outFormat) = 0;
32  // Implement per BFileInterface::DisposeFileFormatCookie
33  // DisposeInputFormatCookie: required for BFileInterface functionality
34  virtual void DisposeInputFormatCookie(int32 cookie) = 0;
35
36/* begin transcoding functions */
37  // These are used to enumerate the set of file formats that this
38  // extractor is prepared to transcode to.  The default implementation
39  // simply returns no support.
40
41  // Implement per BFileInterface::GetNextFileFormat
42  //
43  // Return codes:
44  // B_OK : No error
45  // B_ERROR : No more formats
46  virtual status_t GetNextOutputFormat(int32 * cookie,
47                                       media_file_format * outFormat);
48  // Implement per BFileInterface::DisposeFileFormatCookie
49  virtual void DisposeOutputFormatCookie(int32 cookie);
50/* end transcoding functions */
51/* end BFileInterface functions */
52
53/* begin BMediaAddOn functions */
54  // These are used to discover an extractors quality rating for a
55  // particular media format.
56  // Implement per BMediaAddOn::SniffType
57  //
58  // Return codes:
59  // B_OK : No error
60  // B_MEDIA_NO_HANDLER : This extractor doesn't handle that mime type
61  virtual status_t SniffInputType(BMimeType & mimeType, float * outQuality) = 0;
62/* begin transcoding function */
63  virtual status_t SniffOutputType(BMimeType & mimeType, float * outQuality);
64/* end transcoding function */
65/* end BMediaAddOn functions */
66
67  // Same as above, but for a media file format
68  // The default implementation of this will iterate through your formats using
69  // the appropriate interface from above, and simply return 0 for the quality
70  // if it finds a matching supported format.
71  //
72  // Return codes:
73  // B_OK : No error
74  // B_MEDIA_NO_HANDLER : This extractor doesn't handle that format
75  virtual status_t SniffInputFormat(const media_file_format & format, float * outQuality);
76/* begin transcoding function */
77  virtual status_t SniffOutputFormat(const media_file_format & format, float * outQuality);
78/* end transcoding function */
79
80  //// state creation functions
81  // calling these functions shouldn't affect the results of the stateless functions
82
83  // Sets the current stream to source or destination
84  // The default implementation for the BDataIO SetSource is to wrap
85  // the BDataIO object in a buffer and call the BPositionIO SetSource.
86  // The default implementation for the BFile SetSource is to send the
87  // call directly to BPositionIO.  Note that it is highly recommended
88  // to utilize the BNode properties of the BNodeIO/BFile object in
89  // order to dynamically update your extractor state when the file
90  // changes.  It is also recommended to use the BNode properties in
91  // order to access the attributes of the source file; store or load
92  // file specific extractor properties from here.
93  // Note: the extractor is not require to return B_MEDIA_NO_HANDLER at
94  // this point.  However, calling any stateful function after this
95  // should return B_MEDIA_NO_HANDLER.
96  //
97  // Return codes:
98  // B_OK : No error
99  // B_NO_MEMORY : Storage for the buffer could not be allocated.
100  // B_MEDIA_NO_HANDLER : This extractor doesn't handle that format
101  virtual status_t SetSource(const BFile * source);
102  virtual status_t SetSource(const entry_ref * source, int32 flags = 0);
103  virtual status_t SetSource(const BDataIO * source);
104/* begin transcoding functions */
105  virtual status_t SetDestination(const BFile * source);
106  virtual status_t SetDestination(const entry_ref * source, int32 flags = 0);
107  virtual status_t SetDestination(const BDataIO * source);
108/* end transcoding functions */
109
110  //// stateful functions
111  // Calling these functions shouldn't affect the results of the stateless functions.
112  // Calling these functions before calling a state creation function should return
113  // B_NO_INIT.  Calling these functions after calling a state creation function with
114  // an invalid argument should return B_MEDIA_NO_HANDLER.  Generally these
115  // functions may also return any appropriate Storage Kit/File System Errors, such
116  // as B_FILE_NOT_FOUND, B_BUSTED_PIPE, etc.
117
118  // inspired by BMediaFile::GetFileFormatInfo
119  //
120  // Fills the specified media_file_format structure with
121  // information describing the file format of the stream
122  // currently referenced by the BEncoder.
123  //
124  // Return codes:
125  // B_OK        : No error
126  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
127  // B_NO_MEMORY : Storage for part of the media_file_format
128  //               object couldn't be allocated.
129  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
130  virtual status_t GetFileFormatInfo(media_file_format * mfi) = 0;
131
132  // The extractor should implement this function in the
133  // manner described for BFileInterface::SniffRef, except that
134  // it uses the current Source instead of an entry_ref
135  //
136  // Return codes:
137  // B_OK : No error
138  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
139  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
140  virtual status_t Sniff(char * outMimeType, float * outQuality) = 0;
141
142  // implement per BMediaTrack::AddChunk(void)
143  //
144  // Return codes:
145  // B_OK        : No error
146  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
147  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
148  virtual status_t WriteChunk(int32 type,
149                              const void * data,
150                              size_t size);
151
152/* begin weird function that is missing but parallels add chunk */
153  // implement per BMediaTrack::ReadChunk(void) <- missing????
154  // umm.. has the same semantics as AddChunk, yeah that's it...
155  //
156  // Return codes:
157  // B_OK        : No error
158  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
159  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
160  virtual status_t ReadChunk(int32 * outType,
161                             const void * outData,
162                             size_t * outSize);
163/* end weird function that is missing but parallels add chunk */
164
165  // The extractor should do any cleanup required.  After
166  // this function returns, the source object should be
167  // closed and deleted by the caller, not by Close().
168  // The default implementation simply returns B_OK.
169  //
170  // Return codes:
171  // B_OK : No error
172  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
173  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
174  virtual status_t Close(void);
175
176  //// shared state functions
177  // The ParameterWeb interface is used to publish both file specific
178  // and extractor specific options.  Accessing a file specific parameter
179  // before calling a state creation function should return B_NO_INIT.
180  // Accessing a file parameter after calling a state creation function
181  // with an invalid argument should return B_MEDIA_NO_HANDLER.  Accessing
182  // extractor specific options should never return these errors, but may
183  // return other errors.
184
185  // the extractor should provide several basic parameters
186  // through this interface, such as B_TRACK_COUNT, and B_DURATION
187  // see also BMediaFile::GetParameterValue
188  // hmmm... how to pick which stream parameters apply to?
189  // could use a bitwise or with B_OUTPUT_STREAM (and a
190  // B_INPUT_STREAM for completeness)
191  //
192  // Return codes:
193  // B_OK : No error
194  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
195  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
196  virtual status_t GetParameterValue(int32 id, const void * value,
197                                     size_t * size) = 0;
198
199  // the extractor may optionally supply parameters for the
200  // user to configure, such as buffering information(?)
201  // see also BMediaFile::SetParameterValue
202  //
203  // Return codes:
204  // B_OK : No error
205  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
206  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
207  virtual status_t SetParameterValue(int32 id, const void * value,
208                                     size_t size);
209
210  // The extractor may return a BParameterWeb for browsing or
211  // configuring the extractor's parameters.  Returns NULL if the
212  // extractor doesn't support this.  The default implementation
213  // simply returns NULL.  Note: if the Source is not in a good
214  // state, this web may not include file specific parameters.
215  //
216  // As a suggestion you should use groups to gather parameters
217  // related to the encoder and separate them from parameters
218  // related to the input stream and output stream (if applicable)
219  //
220  // See also BMediaFile::Web
221  virtual BParameterWeb * Web(void) { return NULL; }
222
223  // The extractor may return a BView for browsing or configuring
224  // the extractor's parameters.  Returns NULL if the extractor
225  // doesn't support this.  The default implementation simply
226  // returns NULL.
227  virtual BView * GetParameterView(void) (void) { return NULL; }
228
229/* begin seek/sync functions for the extractor */
230  // The extractor will seek first on the seek track, just like
231  // BMediaTrack::SeekToTime.  Like SeekToTime, it accepts a flag
232  // argument which tells how to find the nearest acceptable frame.
233  // After finding this frame, it will also seek any other open
234  // streams in an extractor-dependent fashion.  Usually the seek
235  // stream will be a video stream.  If seeked to a keyframe, for
236  // example, the audio stream will be seeked to an appropriate time.
237  //
238  // This may be more efficient than seeking the seek track through
239  // the BMediaTrack interface, and then calling Sync() here.  It
240  // should not be less efficient.
241  //
242  // See also BMediaTrack::SeekToTime
243  // see above for additions to media_seek_type (used for flags)
244  // seekMode per BFile::Seek, only SEEK_SET is required
245  //
246  // Return codes:
247  // B_OK : No error
248  // B_UNSUPPORTED : This extractor does not support general seeking
249  //                 for this stream.
250  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
251  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
252  virtual status_t SeekToTime(bigtime_t * ioTime,
253                              int32 mediaSeekFlags = 0,
254                              int32 seekMode = 0) = 0;
255
256  // The extractor will seek first on the seek track, just like
257  // BMediaTrack::SeekToFrame.  Like SeekToFrame, it accepts a flag
258  // argument which tells how to find the nearest acceptable frame.
259  // After finding this frame, it will also seek any other open
260  // streams in an extractor-dependent fashion.  Usually the seek
261  // stream will be a video stream.  If seeked to a keyframe, for
262  // example, the audio stream will be seeked to an appropriate time.
263  //
264  // This may be more efficient than seeking the seek track through
265  // the BMediaTrack interface, and then calling Sync() here.  It
266  // should not be less efficient.
267  //
268  // See also BMediaTrack::SeekToFrame
269  // see above for additions to media_seek_type (used for flags)
270  // seekMode per BFile::Seek, only SEEK_SET is required
271  //
272  // Return codes:
273  // B_OK : No error
274  // B_UNSUPPORTED : This extractor does not support general seeking
275  //                 for this stream.
276  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
277  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
278  virtual status_t SeekToFrame(int64 * ioFrame,
279                               int32 mediaSeekFlags = 0,
280                               int32 seekMode = 0) = 0;
281
282/* begin seek extensions functions */
283  // The extractor will seek first on the seek track.  It goes to
284  // a position defined by ioChunk*chunkSize, where chunkSize is
285  // defined by the decoder.  For example, some streams are not byte
286  // streams, but rather bitstreams.  In this case the chunkSize may
287  // correspond to 1 bit.  Like the other MediaTrack Seeks, it
288  // accepts a flag argument which tells how to find the nearest
289  // acceptable frame.
290  // After finding this frame, it will also seek any other open
291  // streams in an extractor-dependent fashion.  Usually the seek
292  // stream will be a video stream.  If seeked to a keyframe, for
293  // example, the audio stream will be seeked to an appropriate time.
294  //
295  // This may be more efficient than seeking the seek track through
296  // the BMediaTrack interface, and then calling Sync() here.  It
297  // should not be less efficient.
298  //
299  // see above for additions to media_seek_type (used for flags)
300  // seekMode per BFile::Seek, only SEEK_SET is required
301  //
302  // Return codes:
303  // B_OK : No error
304  // B_UNSUPPORTED : This extractor does not support general seeking
305  //                 for this stream.
306  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
307  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
308  virtual status_t SeekToChunk(int64 * ioChunk,
309                               int32 mediaSeekFlags = 0,
310                               int32 seekMode = 0) = 0;
311
312  // The extractor will seek first on the seek track.  It goes to a
313  // position defined by numerator/(duration of this file).  For
314  // example: Seek(LONG_LONG_MAX/2) would seek halfway through the
315  // stream.  Like the other MediaTrack Seeks, it accepts a flag
316  // argument which tells how to find the nearest acceptable frame.
317  // If the seekMode is SEEK_SET it will seek a fraction of the way
318  // back to the beginning from the current location.  If the seekMode
319  // is SEEK_END it will seek a fraction of the way to the end from
320  // the current location.  If the seekMode is SEEK_CUR it will seek
321  // as above. (fraction of the entire file duration)
322  // After finding this frame, it will also seek any other open
323  // streams in an extractor-dependent fashion.  Usually the seek
324  // stream will be a video stream.  If seeked to a keyframe, for
325  // example, the audio stream will be seeked to an appropriate time.
326  //
327  // This may be a lot more efficient than seeking to a time or frame
328  // for some streams. (in particular, nonindexed streams)
329  //
330  // This may be more efficient than seeking the seek track through
331  // the BMediaTrack interface, and then calling Sync() here.  It
332  // should not be less efficient.
333  //
334  // Note: because the duration may change over time (if the file is
335  // being written to, for example) the result of seeking with a
336  // particular numerator may also change.  It will usually be later,
337  // but could also be earlier.
338  //
339  // see above for additions to media_seek_type (used for flags)
340  // seekMode per BFile::Seek, only SEEK_CUR is required
341  //
342  // Return codes:
343  // B_OK : No error
344  // B_UNSUPPORTED : This extractor does not support general seeking
345  //                 for this stream.
346  // B_NO_INIT     : The BEncoder doesn't reference a valid stream.
347  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
348  virtual status_t Seek(int64 * numerator,
349                        int32 mediaSeekFlags = 0,
350                        int32 seekMode = 0) = 0;
351/* end seek extensions functions */
352
353  // Using the location from the seek stream, seeks any other open
354  // streams in an extractor-dependent fashion.  Usually the seek
355  // stream will be a video stream.  If seeked to a keyframe, for
356  // example, the audio stream will be seeked to an appropriate time.
357  //
358  // Note: if not supplied, the seek stream will be the current one
359  // as retrieved by GetParameterValue, not zero.  Sync() will do
360  // this check for you.
361  //
362  // Return codes:
363  // B_OK : No error
364  // B_UNSUPPORTED : This extractor does not support general syncing
365  //                 for this stream.
366  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
367  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
368  virtual status_t Sync(int32 seekStream = 0) = 0;
369/* end seek/sync functions for the extractor */
370
371  // Returns a thing that is useful for MediaTrack to do its business.
372  //
373  // May simply include state but will probably include a pointer back
374  // to this object, and will likely call functions that are defined by
375  // subclasses of this extractor.  For example, the subclass may define
376  // a function like this:
377  // SeekTrackToFrame(BTrack * track, int64 ioFrame, int32 flags = 0) {
378  // ... }
379  // and then when SeekToFrame is called on the BTrack object the work
380  // would be done by the Extractor.
381  //
382  // Also, any track extracted using this function will be seeked by
383  // the extractor seek functions.  Any track not extracted by this
384  // function will not be seeked.  If the seekMode parameter is
385  // supplied as SEEK_CUR the track will be seeked before being
386  // returned, as per Sync().  However because this involves only
387  // one track it may be more efficient than retrieving the track and
388  // then calling Sync();  If seekMode is SEEK_SET then the current
389  // seek time for the track will be no later than the earliest
390  // seekable time.  If seekMode is SEEK_END the current seek time
391  // for the track will be no earlier than the earliest seekable time.
392  // Note: for non-seekable tracks, this may may no difference.
393  // The default for seekMode is SEEK_SET.
394  //
395  // If the seek parameter is passed as false, no pre-seeking will be
396  // performed on the track.  The current seek time may be arbitrary
397  // or even illegal.  Attempting to decode data from the track in
398  // this state will result in an error if the state is illegal.
399  //
400  // Return codes:
401  // B_OK : No error
402  // B_STREAM_NOT_FOUND
403  // B_BAD_INDEX : The index supplied does not correspond to a valid
404  //               track in this stream.
405  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
406  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
407  virtual BTrack * TrackAt(int32 index, int32 seekMode = 0,
408                                        bool seek = true) = 0;
409
410  // Disclaims interest in a particular track.  After releasing a
411  // track the track will no longer be seeked by the extractor.
412  //
413  // Return codes:
414  // B_OK : No error
415  // B_BAD_TYPE  : This track does not correspond to this extractor.
416  // B_NO_INIT   : The BEncoder doesn't reference a valid stream.
417  // B_MEDIA_NO_HANDLER : This extractor doesn't handle this format
418  status_t ReleaseTrack(BTrack * track);
419
420protected:
421  // use to negotiate the format for this track
422  // straight BMediaTrack::DecodedFormat behavior
423  virtual status_t NegotiateOutputFormat(BTrack * track,
424                                         media_format * ioFormat) = 0;
425
426  // get/set information about a particular track
427  virtual status_t GetParameterValue(BTrack * track, int32 id,
428                                     const void * value, size_t * size) = 0;
429  virtual status_t SetParameterValue(BTrack * track, int32 id,
430                                     const void * value, size_t size);
431  virtual BParameterWeb * Web(BTrack * track) { return NULL; }
432  virtual BView * GetParameterView(BTrack * track) { return NULL; }
433
434  // seek only this particular track to the given time
435  // straight BMediaTrack::SeekToTime behavior
436  virtual status_t SeekToTime(BTrack * track,
437                              bigtime_t * ioTime,
438                              int32 mediaSeekFlags = 0,
439                              int32 seekMode = 0) = 0;
440  // seek only this particular track to the given frame
441  // straight BMediaTrack::SeekToFrame behavior
442  virtual status_t SeekToFrame(BTrack * track,
443                               int64 * ioFrame,
444                               int32 mediaSeekFlags = 0,
445                               int32 seekMode = 0) = 0;
446  // seek only this particular track to the given chunk
447  // straight BMediaTrack::SeekToChunk behavior
448  virtual status_t SeekToChunk(BTrack * track,
449                               int64 * ioChunk,
450                               int32 mediaSeekFlags = 0,
451                               int32 seekMode = 0) = 0;
452  // seek only this particular track to the given chunk
453  // straight BMediaTrack::Seek behavior
454  virtual status_t Seek(BTrack * track,
455                        int64 * numerator,
456                        int32 mediaSeekFlags = 0,
457                        int32 seekMode = 0) = 0;
458
459  // read a chunk from this track only
460  // straight BMediaTrack::ReadChunk behavior
461  virtual status_t ReadChunk(BTrack * track,
462                             char ** outBuffer, int32 * ioSize,
463                             media_header * outHeader = NULL) = 0;
464  // read frames from this track only
465  // straight BMediaTrack::ReadChunk behavior
466  virtual status_t ReadFrames(BTrack * track,
467                              void * outBuffer, int64 * outFrameCount,
468                              media_header * outHeader = NULL,
469                              media_decode_info * info = NULL) = 0;
470/* begin read extensions functions */
471  // read units of time from this track only
472  virtual status_t ReadTime(BTrack * track,
473                            void * outBuffer, int64 * outTimeCount,
474                            media_header * outHeader = NULL,
475                            media_decode_info * info = NULL) = 0;
476  // for completeness sake?
477  // read a percentage from this track only
478  virtual status_t Read(BTrack * track,
479                        void * outBuffer, int64 * outNumerator,
480                        media_header * outHeader = NULL,
481                        media_decode_info * info = NULL) = 0;
482/* end read extensions functions */
483
484private:
485  // this class is used by individual tracks
486  // as a private interface to the extractor
487  class BTrack {
488    // use to negotiate the format for this track
489    virtual status_t NegotiateOutputFormat(media_format * ioFormat) {
490      return BExtractor::NegotiateOutputFormat(ioFormat);
491    }
492
493    // access to parameters for this track
494    virtual status_t GetParameterValue(int32 id, const void * value,
495                                       size_t * size) {
496      return BExtractor::GetParameterValue(this,id,value,size);
497    }
498    virtual status_t SetParameterValue(int32 id, const void * value,
499                                       size_t size) {
500      return BExtractor::SetParameterValue(this,id,value,size);
501    }
502    virtual BParameterWeb * Web(void) {
503      return BExtractor::Web(this);
504    }
505    virtual BView * GetParameterView(void) {
506      return BExtractor::GetParameterView(this);
507    }
508
509    // access to seek functionality on this track
510    virtual status_t SeekToTime(bigtime_t * ioTime,
511                              int32 mediaSeekFlags = 0,
512                              int32 seekMode = 0) {
513      return BExtractor::SeekToTime(this,ioTime,mediaSeekFlags,seekMode);
514    }
515    virtual status_t SeekToFrame(int64 * ioFrame,
516                                 int32 mediaSeekFlags = 0,
517                                 int32 seekMode = 0) {
518      return BExtractor::SeekToFrame(this,ioFrame,mediaSeekFlags,seekMode);
519    }
520    virtual status_t SeekToChunk(int64 * ioChunk,
521                                 int32 mediaSeekFlags = 0,
522                                 int32 seekMode = 0) {
523      return BExtractor::SeekToChunk(this,ioChunk,mediaSeekFlags,seekMode);
524    }
525    virtual status_t Seek(int64 * numerator,
526                          int32 mediaSeekFlags = 0,
527                          int32 seekMode = 0) {
528      return BExtractor::Seek(this,numerator,mediaSeekFlags,seekMode);
529    }
530
531    // access to readers for this track
532    virtual status_t ReadChunk(char ** outBuffer, int32 * ioSize,
533                               media_header * outHeader = NULL) {
534      return BExtractor::ReadChunk(this,outBuffer,ioSize,outHeader);
535    }
536    virtual status_t ReadFrames(void * outBuffer, int64 * outFrameCount,
537                                media_header * outHeader = NULL,
538                                media_decode_info * info = NULL) {
539      return BExtractor::ReadFrames(this,outBuffer,outFrameCount,outHeader,info);
540    }
541/* begin read extensions functions */
542	virtual status_t ReadTime(void * outBuffer, int64 * outTimeCount,
543                              media_header * outHeader = NULL,
544                              media_decode_info * info = NULL) {
545      return BExtractor::ReadTime(this,outBuffer,outTimeCount,outHeader,info);
546    }
547    // for completeness sake?
548    virtual status_t Read(void * outBuffer, int64 * outNumerator,
549                          media_header * outHeader = NULL,
550                          media_decode_info * info = NULL) {
551      return BExtractor::Read(this,outBuffer,outNumerator,outHeader,info);
552    }
553/* end read extensions functions */
554    // pad me
555  };
556
557  // pad me
558};
559
560
561