1 extern "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 10 class BMediaExtractorAddOn 11 { 12 public: 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 420 protected: 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 484 private: 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