@ -207,19 +207,19 @@ static bool Resync(
return valid ;
}
class MP3Source : public MediaTrackHelper {
class MP3Source : public MediaTrackHelper V2 {
public :
MP3Source (
MetaDataBase & meta , DataSourceHelper * source ,
AMediaFormat * meta , DataSourceHelper * source ,
off64_t first_frame_pos , uint32_t fixed_header ,
MP3Seeker * seeker ) ;
virtual status_t start ( ) ;
virtual status_t stop ( ) ;
virtual media_ status_t start ( ) ;
virtual media_ status_t stop ( ) ;
virtual status_t getFormat ( MetaDataBase & meta ) ;
virtual media_status_t getFormat ( AMediaFormat * meta ) ;
virtual status_t read (
virtual media_ status_t read (
MediaBufferBase * * buffer , const ReadOptions * options = NULL ) ;
protected :
@ -227,7 +227,7 @@ protected:
private :
static const size_t kMaxFrameSize ;
MetaDataBase & mMeta ;
AMediaFormat * mMeta ;
DataSourceHelper * mDataSource ;
off64_t mFirstFramePos ;
uint32_t mFixedHeader ;
@ -283,6 +283,7 @@ MP3Extractor::MP3Extractor(
mFixedHeader = header ;
XINGSeeker * seeker = XINGSeeker : : CreateFromSource ( mDataSource , mFirstFramePos ) ;
mMeta = AMediaFormat_new ( ) ;
if ( seeker = = NULL ) {
mSeeker = VBRISeeker : : CreateFromSource ( mDataSource , post_id3_pos ) ;
} else {
@ -290,8 +291,8 @@ MP3Extractor::MP3Extractor(
int encd = seeker - > getEncoderDelay ( ) ;
int encp = seeker - > getEncoderPadding ( ) ;
if ( encd ! = 0 | | encp ! = 0 ) {
mMeta. setInt32 ( kKeyEncoderDelay , encd ) ;
mMeta. setInt32 ( kKeyEncoderPadding , encp ) ;
AMediaFormat_setInt32( mMeta , AMEDIAFORMAT_KEY_ENCODER_DELAY , encd ) ;
AMediaFormat_setInt32( mMeta , AMEDIAFORMAT_KEY_ENCODER_PADDING , encp ) ;
}
}
@ -327,21 +328,23 @@ MP3Extractor::MP3Extractor(
switch ( layer ) {
case 1 :
mMeta . setCString ( kKeyMIMEType , MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I ) ;
AMediaFormat_setString ( mMeta ,
AMEDIAFORMAT_KEY_MIME , MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I ) ;
break ;
case 2 :
mMeta . setCString ( kKeyMIMEType , MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II ) ;
AMediaFormat_setString ( mMeta ,
AMEDIAFORMAT_KEY_MIME , MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II ) ;
break ;
case 3 :
mMeta. setCString ( kKeyMIMEType , MEDIA_MIMETYPE_AUDIO_MPEG ) ;
AMediaFormat_setString( mMeta , AMEDIAFORMAT_KEY_MIME , MEDIA_MIMETYPE_AUDIO_MPEG ) ;
break ;
default :
TRESPASS ( ) ;
}
mMeta. setInt32 ( kKeySampleRate , sample_rate ) ;
mMeta. setInt32 ( kKeyBitRate , bitrate * 1000 ) ;
mMeta. setInt32 ( kKeyChannelCount , num_channels ) ;
AMediaFormat_setInt32( mMeta , AMEDIAFORMAT_KEY_SAMPLE_RATE , sample_rate ) ;
AMediaFormat_setInt32( mMeta , AMEDIAFORMAT_KEY_BIT_RATE , bitrate * 1000 ) ;
AMediaFormat_setInt32( mMeta , AMEDIAFORMAT_KEY_CHANNEL_COUNT , num_channels ) ;
int64_t durationUs ;
@ -361,7 +364,7 @@ MP3Extractor::MP3Extractor(
}
if ( durationUs > = 0 ) {
mMeta. setInt64 ( kKeyDuration , durationUs ) ;
AMediaFormat_setInt64( mMeta , AMEDIAFORMAT_KEY_DURATION , durationUs ) ;
}
mInitCheck = OK ;
@ -389,8 +392,8 @@ MP3Extractor::MP3Extractor(
int32_t delay , padding ;
if ( sscanf ( value , " %*x %x %x %*x " , & delay , & padding ) = = 2 ) {
mMeta. setInt32 ( kKeyEncoderDelay , delay ) ;
mMeta. setInt32 ( kKeyEncoderPadding , padding ) ;
AMediaFormat_setInt32( mMeta , AMEDIAFORMAT_KEY_ENCODER_DELAY , delay ) ;
AMediaFormat_setInt32( mMeta , AMEDIAFORMAT_KEY_ENCODER_PADDING , padding ) ;
}
break ;
}
@ -404,13 +407,14 @@ MP3Extractor::MP3Extractor(
MP3Extractor : : ~ MP3Extractor ( ) {
delete mSeeker ;
delete mDataSource ;
AMediaFormat_delete ( mMeta ) ;
}
size_t MP3Extractor : : countTracks ( ) {
return mInitCheck ! = OK ? 0 : 1 ;
}
MediaTrackHelper * MP3Extractor : : getTrack ( size_t index ) {
MediaTrackHelper V2 * MP3Extractor : : getTrack ( size_t index ) {
if ( mInitCheck ! = OK | | index ! = 0 ) {
return NULL ;
}
@ -420,14 +424,14 @@ MediaTrackHelper *MP3Extractor::getTrack(size_t index) {
mSeeker ) ;
}
status_t MP3Extractor : : getTrackMetaData (
MetaDataBase & meta ,
media_ status_t MP3Extractor : : getTrackMetaData (
AMediaFormat * meta ,
size_t index , uint32_t /* flags */ ) {
if ( mInitCheck ! = OK | | index ! = 0 ) {
return UNKNOWN_ERROR ;
return AMEDIA_ERROR_ UNKNOWN;
}
meta = mMeta ;
return OK;
AMediaFormat_copy( meta , mMeta ) ;
return AMEDIA_ OK;
}
////////////////////////////////////////////////////////////////////////////////
@ -440,7 +444,7 @@ status_t MP3Extractor::getTrackMetaData(
// Set our max frame size to the nearest power of 2 above this size (aka, 4kB)
const size_t MP3Source : : kMaxFrameSize = ( 1 < < 12 ) ; /* 4096 bytes */
MP3Source : : MP3Source (
MetaDataBase & meta , DataSourceHelper * source ,
AMediaFormat * meta , DataSourceHelper * source ,
off64_t first_frame_pos , uint32_t fixed_header ,
MP3Seeker * seeker )
: mMeta ( meta ) ,
@ -462,7 +466,7 @@ MP3Source::~MP3Source() {
}
}
status_t MP3Source : : start ( ) {
media_ status_t MP3Source : : start ( ) {
CHECK ( ! mStarted ) ;
mGroup = new MediaBufferGroup ;
@ -477,10 +481,10 @@ status_t MP3Source::start() {
mStarted = true ;
return OK;
return AMEDIA_ OK;
}
status_t MP3Source : : stop ( ) {
media_ status_t MP3Source : : stop ( ) {
CHECK ( mStarted ) ;
delete mGroup ;
@ -488,15 +492,14 @@ status_t MP3Source::stop() {
mStarted = false ;
return OK;
return AMEDIA_ OK;
}
status_t MP3Source : : getFormat ( MetaDataBase & meta ) {
meta = mMeta ;
return OK ;
media_status_t MP3Source : : getFormat ( AMediaFormat * meta ) {
return AMediaFormat_copy ( meta , mMeta ) ;
}
status_t MP3Source : : read (
media_ status_t MP3Source : : read (
MediaBufferBase * * out , const ReadOptions * options ) {
* out = NULL ;
@ -509,11 +512,11 @@ status_t MP3Source::read(
if ( mSeeker = = NULL
| | ! mSeeker - > getOffsetForTime ( & actualSeekTimeUs , & mCurrentPos ) ) {
int32_t bitrate ;
if ( ! mMeta. findInt32 ( kKeyBitRate , & bitrate ) ) {
if ( ! AMediaFormat_getInt32( mMeta , AMEDIAFORMAT_KEY_BIT_RATE , & bitrate ) ) {
// bitrate is in bits/sec.
ALOGI ( " no bitrate " ) ;
return ERROR_UNSUPPORTED;
return AMEDIA_ ERROR_UNSUPPORTED;
}
mCurrentTimeUs = seekTimeUs ;
@ -530,7 +533,7 @@ status_t MP3Source::read(
MediaBufferBase * buffer ;
status_t err = mGroup - > acquire_buffer ( & buffer ) ;
if ( err ! = OK ) {
return err ;
return AMEDIA_ERROR_UNKNOWN ;
}
size_t frame_size ;
@ -543,7 +546,7 @@ status_t MP3Source::read(
buffer - > release ( ) ;
buffer = NULL ;
return ( n < 0 ? n : ERROR_END_OF_STREAM) ;
return ( n < 0 ? AMEDIA_ERROR_UNKNOWN : AMEDIA_ ERROR_END_OF_STREAM) ;
}
uint32_t header = U32_AT ( ( const uint8_t * ) buffer - > data ( ) ) ;
@ -572,7 +575,7 @@ status_t MP3Source::read(
buffer - > release ( ) ;
buffer = NULL ;
return ERROR_END_OF_STREAM;
return AMEDIA_ ERROR_END_OF_STREAM;
}
mCurrentPos = pos ;
@ -587,7 +590,7 @@ status_t MP3Source::read(
buffer - > release ( ) ;
buffer = NULL ;
return ( n < 0 ? n : ERROR_END_OF_STREAM) ;
return ( n < 0 ? AMEDIA_ERROR_UNKNOWN : AMEDIA_ ERROR_END_OF_STREAM) ;
}
buffer - > set_range ( 0 , frame_size ) ;
@ -602,40 +605,40 @@ status_t MP3Source::read(
* out = buffer ;
return OK;
return AMEDIA_ OK;
}
status_t MP3Extractor : : getMetaData ( MetaDataBase & meta ) {
meta. clear ( ) ;
media_ status_t MP3Extractor : : getMetaData ( AMediaFormat * meta ) {
AMediaFormat_clear( meta ) ;
if ( mInitCheck ! = OK ) {
return UNKNOWN_ERROR ;
return AMEDIA_ERROR_ UNKNOWN;
}
meta. setCString ( kKeyMIMEType , " audio/mpeg " ) ;
AMediaFormat_setString( meta , AMEDIAFORMAT_KEY_MIME , " audio/mpeg " ) ;
DataSourceHelper helper ( mDataSource ) ;
ID3 id3 ( & helper ) ;
if ( ! id3 . isValid ( ) ) {
return OK;
return AMEDIA_ OK;
}
struct Map {
int key ;
const char * key ;
const char * tag1 ;
const char * tag2 ;
} ;
static const Map kMap [ ] = {
{ kKeyAlbum , " TALB " , " TAL " } ,
{ kKeyArtist , " TPE1 " , " TP1 " } ,
{ kKeyAlbumArtist , " TPE2 " , " TP2 " } ,
{ kKeyComposer , " TCOM " , " TCM " } ,
{ kKeyGenre , " TCON " , " TCO " } ,
{ kKeyTitle , " TIT2 " , " TT2 " } ,
{ kKeyYear , " TYE " , " TYER " } ,
{ kKeyAuthor , " TXT " , " TEXT " } ,
{ kKeyCDTrackNumber , " TRK " , " TRCK " } ,
{ kKeyDiscNumber , " TPA " , " TPOS " } ,
{ kKeyCompilation , " TCP " , " TCMP " } ,
{ AMEDIAFORMAT_KEY_ALBUM , " TALB " , " TAL " } ,
{ AMEDIAFORMAT_KEY_ARTIST , " TPE1 " , " TP1 " } ,
{ AMEDIAFORMAT_KEY_ALBUMARTIST , " TPE2 " , " TP2 " } ,
{ AMEDIAFORMAT_KEY_COMPOSER , " TCOM " , " TCM " } ,
{ AMEDIAFORMAT_KEY_GENRE , " TCON " , " TCO " } ,
{ AMEDIAFORMAT_KEY_TITLE , " TIT2 " , " TT2 " } ,
{ AMEDIAFORMAT_KEY_YEAR , " TYE " , " TYER " } ,
{ AMEDIAFORMAT_KEY_AUTHOR , " TXT " , " TEXT " } ,
{ AMEDIAFORMAT_KEY_CDTRACKNUMBER , " TRK " , " TRCK " } ,
{ AMEDIAFORMAT_KEY_DISCNUMBER , " TPA " , " TPOS " } ,
{ AMEDIAFORMAT_KEY_COMPILATION , " TCP " , " TCMP " } ,
} ;
static const size_t kNumMapEntries = sizeof ( kMap ) / sizeof ( kMap [ 0 ] ) ;
@ -655,7 +658,7 @@ status_t MP3Extractor::getMetaData(MetaDataBase &meta) {
it - > getString ( & s ) ;
delete it ;
meta. setCString ( kMap [ i ] . key , s ) ;
AMediaFormat_setString( meta , kMap [ i ] . key , s . string ( ) ) ;
}
size_t dataSize ;
@ -663,21 +666,20 @@ status_t MP3Extractor::getMetaData(MetaDataBase &meta) {
const void * data = id3 . getAlbumArt ( & dataSize , & mime ) ;
if ( data ) {
meta . setData ( kKeyAlbumArt , MetaData : : TYPE_NONE , data , dataSize ) ;
meta . setCString ( kKeyAlbumArtMIME , mime . string ( ) ) ;
AMediaFormat_setBuffer ( meta , AMEDIAFORMAT_KEY_ALBUMART , data , dataSize ) ;
}
return OK;
return AMEDIA_ OK;
}
static CMediaExtractor * CreateExtractor (
static CMediaExtractor V2 * CreateExtractor (
CDataSource * source ,
void * meta ) {
Mp3Meta * metaData = static_cast < Mp3Meta * > ( meta ) ;
return wrap ( new MP3Extractor ( new DataSourceHelper ( source ) , metaData ) ) ;
return wrap V2 ( new MP3Extractor ( new DataSourceHelper ( source ) , metaData ) ) ;
}
static CreatorFunc Sniff (
static CreatorFunc V2 Sniff (
CDataSource * source , float * confidence , void * * meta ,
FreeMetaFunc * freeMeta ) {
off64_t pos = 0 ;
@ -714,11 +716,11 @@ extern "C" {
__attribute__ ( ( visibility ( " default " ) ) )
ExtractorDef GETEXTRACTORDEF ( ) {
return {
EXTRACTORDEF_VERSION ,
EXTRACTORDEF_VERSION _CURRENT ,
UUID ( " 812a3f6c-c8cf-46de-b529-3774b14103d4 " ) ,
1 , // version
" MP3 Extractor " ,
{ Sniff }
{ . v2 = Sniff }
} ;
}