@ -52,6 +52,7 @@ namespace android {
OggWriter : : OggWriter ( int fd )
: mFd ( dup ( fd ) ) ,
mHaveAllCodecSpecificData ( false ) ,
mInitCheck ( mFd < 0 ? NO_INIT : OK ) {
// empty
}
@ -115,17 +116,26 @@ status_t OggWriter::addSource(const sp<MediaSource>& source) {
mSampleRate = sampleRate ;
uint32_t type ;
const void * header_data ;
size_t packet_size ;
const void * header_data = NULL ;
size_t packet_size = 0 ;
if ( ! source - > getFormat ( ) - > findData ( kKeyOpusHeader , & type , & header_data , & packet_size ) ) {
ALOGE ( " opus header not found " ) ;
return UNKNOWN_ERROR ;
ALOGV ( " opus header not found in format " ) ;
} else if ( header_data & & packet_size ) {
writeOggHeaderPackets ( ( unsigned char * ) header_data , packet_size ) ;
} else {
ALOGD ( " ignoring incomplete opus header data in format " ) ;
}
mSource = source ;
return OK ;
}
status_t OggWriter : : writeOggHeaderPackets ( unsigned char * buf , size_t size ) {
ogg_packet op ;
ogg_page og ;
op . packet = ( unsigned char * ) header_data ;
op . bytes = packet_size ;
op . packet = buf ;
op . bytes = size;
op . b_o_s = 1 ;
op . e_o_s = 0 ;
op . granulepos = 0 ;
@ -169,8 +179,8 @@ status_t OggWriter::addSource(const sp<MediaSource>& source) {
write ( mFd , og . body , og . body_len ) ;
}
mSource = source ;
free ( comments ) ;
mHaveAllCodecSpecificData = true ;
return OK ;
}
@ -301,12 +311,35 @@ status_t OggWriter::threadFunc() {
& & isCodecSpecific )
| | IsOpusHeader ( ( uint8_t * ) buffer - > data ( ) + buffer - > range_offset ( ) ,
buffer - > range_length ( ) ) ) {
ALOGV ( " Drop codec specific info buffer " ) ;
if ( mHaveAllCodecSpecificData = = false ) {
size_t opusHeadSize = 0 ;
size_t codecDelayBufSize = 0 ;
size_t seekPreRollBufSize = 0 ;
void * opusHeadBuf = NULL ;
void * codecDelayBuf = NULL ;
void * seekPreRollBuf = NULL ;
GetOpusHeaderBuffers ( ( uint8_t * ) buffer - > data ( ) + buffer - > range_offset ( ) ,
buffer - > range_length ( ) , & opusHeadBuf ,
& opusHeadSize , & codecDelayBuf ,
& codecDelayBufSize , & seekPreRollBuf ,
& seekPreRollBufSize ) ;
writeOggHeaderPackets ( ( unsigned char * ) opusHeadBuf , opusHeadSize ) ;
} else {
ALOGV ( " ignoring later copy of CSD contained in info buffer " ) ;
}
buffer - > release ( ) ;
buffer = nullptr ;
continue ;
}
if ( mHaveAllCodecSpecificData = = false ) {
ALOGE ( " Did not get valid opus header before first sample data " ) ;
buffer - > release ( ) ;
buffer = nullptr ;
err = ERROR_MALFORMED ;
break ;
}
int64_t timestampUs ;
CHECK ( buffer - > meta_data ( ) . findInt64 ( kKeyTime , & timestampUs ) ) ;
if ( timestampUs > mEstimatedDurationUs ) {