diff options
author | Rajneesh Chowdury <rajneeshc@google.com> | 2011-07-01 18:06:15 -0700 |
---|---|---|
committer | Rajneesh Chowdury <rajneeshc@google.com> | 2011-07-07 15:47:58 -0700 |
commit | bc8e52dadeb078c45e62ebda17fd95e67f689654 (patch) | |
tree | 4958ca3a550f66364a0a3987bcf76b469498b617 /libvideoeditor/vss | |
parent | b13adac0f1ce1792151192966e428d1eed3ef826 (diff) | |
download | frameworks_av-bc8e52dadeb078c45e62ebda17fd95e67f689654.zip frameworks_av-bc8e52dadeb078c45e62ebda17fd95e67f689654.tar.gz frameworks_av-bc8e52dadeb078c45e62ebda17fd95e67f689654.tar.bz2 |
Fix of issue 4973565 Cannot export movie.
Also fixes 4441452 Native Crash after applying transition
Change-Id: Ic48c44bc2c5d07e57edb8f63393cea424d3275f4
Diffstat (limited to 'libvideoeditor/vss')
-rwxr-xr-x | libvideoeditor/vss/common/inc/M4AD_Common.h | 20 | ||||
-rwxr-xr-x | libvideoeditor/vss/mcs/src/M4MCS_API.c | 167 | ||||
-rwxr-xr-x | libvideoeditor/vss/src/M4VSS3GPP_Clip.c | 158 | ||||
-rwxr-xr-x | libvideoeditor/vss/src/M4VSS3GPP_EditAudio.c | 42 | ||||
-rwxr-xr-x | libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp | 210 |
5 files changed, 470 insertions, 127 deletions
diff --git a/libvideoeditor/vss/common/inc/M4AD_Common.h b/libvideoeditor/vss/common/inc/M4AD_Common.h index 7efee24..f6e596d 100755 --- a/libvideoeditor/vss/common/inc/M4AD_Common.h +++ b/libvideoeditor/vss/common/inc/M4AD_Common.h @@ -67,7 +67,25 @@ typedef enum /** * Get the number of used bytes in the latest decode (used only when decoding AAC from ADIF file) */ - M4AD_kOptionID_UsedBytes = M4OSA_OPTION_ID_CREATE(M4_READ , M4DECODER_AUDIO, 0x11) + M4AD_kOptionID_UsedBytes = M4OSA_OPTION_ID_CREATE(M4_READ , M4DECODER_AUDIO, 0x11), + + /* Reader Interface */ + M4AD_kOptionID_3gpReaderInterface = M4OSA_OPTION_ID_CREATE(M4_READ, M4DECODER_AUDIO, 0x012), + + /* Audio Access Unit */ + M4AD_kOptionID_AudioAU = M4OSA_OPTION_ID_CREATE(M4_READ, M4DECODER_AUDIO, 0x13), + + /* Reader error code */ + M4AD_kOptionID_GetAudioAUErrCode = M4OSA_OPTION_ID_CREATE(M4_READ, M4DECODER_AUDIO, 0x14), + + /* Number of channels */ + M4AD_kOptionID_AudioNbChannels = M4OSA_OPTION_ID_CREATE(M4_READ, M4DECODER_AUDIO, 0x15), + + /* Sampling frequency */ + M4AD_kOptionID_AudioSampFrequency = M4OSA_OPTION_ID_CREATE(M4_READ, M4DECODER_AUDIO, 0x16), + + /* Audio AU CTS */ + M4AD_kOptionID_AuCTS = M4OSA_OPTION_ID_CREATE(M4_READ, M4DECODER_AUDIO, 0x17) } M4AD_OptionID; diff --git a/libvideoeditor/vss/mcs/src/M4MCS_API.c b/libvideoeditor/vss/mcs/src/M4MCS_API.c index 20a3524..4a4008b 100755 --- a/libvideoeditor/vss/mcs/src/M4MCS_API.c +++ b/libvideoeditor/vss/mcs/src/M4MCS_API.c @@ -119,6 +119,8 @@ static M4OSA_ERR M4MCS_intCleanUp_ReadersDecoders( static M4OSA_ERR M4MCS_intReallocTemporaryAU( M4OSA_MemAddr8 *addr, M4OSA_UInt32 newSize ); +static M4OSA_ERR M4MCS_intCheckAndGetCodecAacProperties( + M4MCS_InternalContext *pC); /** ********************************************************************** @@ -6083,6 +6085,12 @@ static M4OSA_ERR M4MCS_intPrepareAudioProcessing( M4MCS_InternalContext *pC ) M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam); } + pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, + M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt); + + pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, + M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU); + if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) { /* Not implemented in all decoders */ @@ -8223,6 +8231,8 @@ static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC ) /*FlB 2009.03.04: apply audio effects if an effect is active*/ M4OSA_Int8 *pActiveEffectNumber = &(pC->pActiveEffectNumber); + uint32_t errCode = M4NO_ERROR; + if( pC->noaudio ) return M4NO_ERROR; @@ -8237,49 +8247,9 @@ static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC ) goto m4mcs_intaudiotranscoding_feed_resampler; } - /* Check if all audio frame has been decoded */ - if( pC->ReaderAudioAU.m_size == 0 ) - { - /** - * Read the next audio AU in the input file */ - err = pC->m_pReaderDataIt->m_pFctGetNextAu(pC->pReaderContext, - (M4_StreamHandler *)pC->pReaderAudioStream, &pC->ReaderAudioAU); - -#ifdef MCS_DUMP_PCM_TO_FILE - - fwrite(pC->ReaderAudioAU.m_dataAddress, pC->ReaderAudioAU.m_size, 1, - file_au_reader); - fwrite("____", 4, 1, file_au_reader); - -#endif - - if( M4WAR_NO_MORE_AU == err ) /**< The audio transcoding is finished */ - { - pC->AudioState = M4MCS_kStreamState_FINISHED; - M4OSA_TRACE2_0( - "M4MCS_intAudioTranscoding():\ - m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); - return err; - } - else if( M4NO_ERROR != err ) - { - M4OSA_TRACE1_1( - "M4MCS_intAudioTranscoding():\ - m_pReaderDataIt->m_pFctGetNextAu(Audio) returns 0x%x", - err); - return err; - } - } - - /** - * Decode the AU */ - pC->AudioDecBufferIn.m_dataAddress = pC->ReaderAudioAU.m_dataAddress; - pC->AudioDecBufferIn.m_bufferSize = pC->ReaderAudioAU.m_size; - pC->AudioDecBufferIn.m_timeStampUs = - (int64_t) (pC->ReaderAudioAU.m_CTS * 1000LL); - err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt, - &pC->AudioDecBufferIn, &pC->AudioDecBufferOut, M4OSA_FALSE); + M4OSA_NULL, &pC->AudioDecBufferOut, M4OSA_FALSE); + if( M4NO_ERROR != err ) { @@ -8296,10 +8266,16 @@ static M4OSA_ERR M4MCS_intAudioTranscoding( M4MCS_InternalContext *pC ) #endif - /* update the part of audio that has been decoded into the frame */ + pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, + M4AD_kOptionID_GetAudioAUErrCode, (M4OSA_DataOption) &errCode); - pC->ReaderAudioAU.m_dataAddress += pC->AudioDecBufferIn.m_bufferSize; - pC->ReaderAudioAU.m_size -= pC->AudioDecBufferIn.m_bufferSize; + if ( M4WAR_NO_MORE_AU == errCode ) { + pC->AudioState = M4MCS_kStreamState_FINISHED; + M4OSA_TRACE2_0( + "M4MCS_intAudioTranscoding():\ + m_pReaderDataIt->m_pFctGetNextAu(audio) returns M4WAR_NO_MORE_AU"); + return errCode; + } /* Set the current position in the decoder out buffer */ pC->pPosInDecBufferOut = pC->AudioDecBufferOut.m_dataAddress; @@ -9839,10 +9815,9 @@ static M4OSA_ERR M4MCS_intGetInputClipProperties( M4MCS_InternalContext *pC ) if( M4DA_StreamTypeAudioAac == pC->pReaderAudioStream->m_basicProperties.m_streamType ) { - if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) - err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( - &pC->pAudioDecCtxt, - pC->pReaderAudioStream, &(pC->AacProperties)); + if( M4OSA_FALSE == pC->bExtOMXAudDecoder ) { + err = M4MCS_intCheckAndGetCodecAacProperties(pC); + } else { err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( @@ -10800,3 +10775,97 @@ M4OSA_ERR M4MCS_open_normalMode(M4MCS_Context pContext, M4OSA_Void* pFileIn, return M4NO_ERROR; } +M4OSA_ERR M4MCS_intCheckAndGetCodecAacProperties( + M4MCS_InternalContext *pC) { + + M4OSA_ERR err = M4NO_ERROR; + M4AD_Buffer outputBuffer; + uint32_t optionValue =0; + + M4OSA_TRACE3_0("M4MCS_intCheckAndGetCodecAacProperties :start"); + + // Decode first audio frame from clip to get properties from codec + + err = pC->m_pAudioDecoder->m_pFctCreateAudioDec( + &pC->pAudioDecCtxt, + pC->pReaderAudioStream, &(pC->AacProperties)); + + pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, + M4AD_kOptionID_3gpReaderInterface, (M4OSA_DataOption) pC->m_pReaderDataIt); + + pC->m_pAudioDecoder->m_pFctSetOptionAudioDec(pC->pAudioDecCtxt, + M4AD_kOptionID_AudioAU, (M4OSA_DataOption) &pC->ReaderAudioAU); + + if( pC->m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) { + + err = pC->m_pAudioDecoder->m_pFctStartAudioDec(pC->pAudioDecCtxt); + if( M4NO_ERROR != err ) { + + M4OSA_TRACE1_1( + "M4MCS_intCheckAndGetCodecAACProperties: m_pFctStartAudioDec \ + returns 0x%x", err); + return err; + } + } + + /** + * Allocate output buffer for the audio decoder */ + outputBuffer.m_bufferSize = + pC->pReaderAudioStream->m_byteFrameLength + * pC->pReaderAudioStream->m_byteSampleSize + * pC->pReaderAudioStream->m_nbChannels; + + if( outputBuffer.m_bufferSize > 0 ) { + + outputBuffer.m_dataAddress = + (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \ + *sizeof(short), M4MCS, (M4OSA_Char *)"outputBuffer.m_bufferSize"); + + if( M4OSA_NULL == outputBuffer.m_dataAddress ) { + + M4OSA_TRACE1_0( + "M4MCS_intCheckAndGetCodecAACProperties():\ + unable to allocate outputBuffer.m_dataAddress, returning M4ERR_ALLOC"); + return M4ERR_ALLOC; + } + } + + err = pC->m_pAudioDecoder->m_pFctStepAudioDec(pC->pAudioDecCtxt, + M4OSA_NULL, &outputBuffer, M4OSA_FALSE); + + if ( err == M4WAR_INFO_FORMAT_CHANGE ) { + + // Get the properties from codec node + pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, + M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue); + + pC->AacProperties.aNumChan = optionValue; + // Reset Reader structure value also + pC->pReaderAudioStream->m_nbChannels = optionValue; + + pC->m_pAudioDecoder->m_pFctGetOptionAudioDec(pC->pAudioDecCtxt, + M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue); + + pC->AacProperties.aSampFreq = optionValue; + // Reset Reader structure value also + pC->pReaderAudioStream->m_samplingFrequency = optionValue; + + } else if( err != M4NO_ERROR) { + M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecAACProperties:\ + m_pFctStepAudioDec returns err = 0x%x", err); + } + + free(outputBuffer.m_dataAddress); + + // Reset the stream reader + err = pC->m_pReader->m_pFctReset(pC->pReaderContext, + (M4_StreamHandler *)pC->pReaderAudioStream); + + if (M4NO_ERROR != err) { + M4OSA_TRACE1_1("M4MCS_intCheckAndGetCodecAACProperties\ + Error in reseting reader: 0x%x", err); + } + + return err; + +} diff --git a/libvideoeditor/vss/src/M4VSS3GPP_Clip.c b/libvideoeditor/vss/src/M4VSS3GPP_Clip.c index 5eaedf7..91ba966 100755 --- a/libvideoeditor/vss/src/M4VSS3GPP_Clip.c +++ b/libvideoeditor/vss/src/M4VSS3GPP_Clip.c @@ -61,6 +61,9 @@ static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder( M4VSS3GPP_ClipContext *pClipCtxt ); +static M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties( + M4VSS3GPP_ClipContext *pClipCtxt); + /** ****************************************************************************** * M4OSA_ERR M4VSS3GPP_intClipOpen() @@ -1140,16 +1143,16 @@ static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder( if( M4OSA_TRUE == pClipCtxt->ShellAPI.bAllowFreeingOMXCodecInterface ) { - /* NXP SW codec interface is used*/ - if( M4DA_StreamTypeAudioAac == audiotype ) - err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( - &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream, - &(pClipCtxt->AacProperties)); - else + if( M4DA_StreamTypeAudioAac == audiotype ) { + err = M4VSS3GPP_intCheckAndGetCodecAacProperties( + pClipCtxt); + } else if (M4DA_StreamTypeAudioPcm != audiotype) { err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( &pClipCtxt->pAudioDecCtxt, pClipCtxt->pAudioStream, - M4OSA_NULL /* to be changed with HW interfaces */); - + M4OSA_NULL); + } else { + err = M4NO_ERROR; + } if( M4NO_ERROR != err ) { M4OSA_TRACE1_1( @@ -1310,6 +1313,16 @@ static M4OSA_ERR M4VSS3GPP_intClipPrepareAudioDecoder( M4AD_kOptionID_UserParam, (M4OSA_DataOption) &AacDecParam); } + if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec ) { + pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( + pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface, + (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt); + + pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( + pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU, + (M4OSA_DataOption) &pClipCtxt->AudioAU); + } + if( M4OSA_NULL != pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec ) { /* Not implemented in all decoders */ @@ -1412,16 +1425,26 @@ M4OSA_ERR M4VSS3GPP_intClipDecodeCurrentAudioFrame( { /** * Decode current AMR frame */ - pClipCtxt->AudioDecBufferIn.m_dataAddress = - (M4OSA_MemAddr8)pClipCtxt->pAudioFramePtr; - pClipCtxt->AudioDecBufferIn.m_bufferSize = pClipCtxt->uiAudioFrameSize; - pClipCtxt->AudioDecBufferIn.m_timeStampUs = - (int64_t) (pClipCtxt->iAudioFrameCts * 1000LL); - - err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( - pClipCtxt->pAudioDecCtxt, - &pClipCtxt->AudioDecBufferIn, &pClipCtxt->AudioDecBufferOut, - M4OSA_FALSE); + if ( pClipCtxt->pAudioFramePtr != M4OSA_NULL ) { + pClipCtxt->AudioDecBufferIn.m_dataAddress = + (M4OSA_MemAddr8)pClipCtxt->pAudioFramePtr; + pClipCtxt->AudioDecBufferIn.m_bufferSize = + pClipCtxt->uiAudioFrameSize; + pClipCtxt->AudioDecBufferIn.m_timeStampUs = + (int64_t) (pClipCtxt->iAudioFrameCts * 1000LL); + + err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( + pClipCtxt->pAudioDecCtxt, + &pClipCtxt->AudioDecBufferIn, &pClipCtxt->AudioDecBufferOut, + M4OSA_FALSE); + } else { + // Pass Null input buffer + // Reader invoked from Audio decoder source + err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( + pClipCtxt->pAudioDecCtxt, + M4OSA_NULL, &pClipCtxt->AudioDecBufferOut, + M4OSA_FALSE); + } if( M4NO_ERROR != err ) { @@ -1953,3 +1976,102 @@ M4OSA_UInt32 M4VSS3GPP_intGetFrameSize_EVRC( M4OSA_MemAddr8 pAudioFrame ) return (1 + (( frameSize + 7) / 8)); } + +M4OSA_ERR M4VSS3GPP_intCheckAndGetCodecAacProperties( + M4VSS3GPP_ClipContext *pClipCtxt) { + + M4OSA_ERR err = M4NO_ERROR; + M4AD_Buffer outputBuffer; + uint32_t optionValue =0; + + // Decode first audio frame from clip to get properties from codec + + err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctCreateAudioDec( + &pClipCtxt->pAudioDecCtxt, + pClipCtxt->pAudioStream, &(pClipCtxt->AacProperties)); + + pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( + pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_3gpReaderInterface, + (M4OSA_DataOption) pClipCtxt->ShellAPI.m_pReaderDataIt); + + pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctSetOptionAudioDec( + pClipCtxt->pAudioDecCtxt, M4AD_kOptionID_AudioAU, + (M4OSA_DataOption) &pClipCtxt->AudioAU); + + if( pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec != M4OSA_NULL ) { + + err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStartAudioDec( + pClipCtxt->pAudioDecCtxt); + if( M4NO_ERROR != err ) { + + M4OSA_TRACE1_1( + "M4VSS3GPP_intCheckAndGetCodecAacProperties: \ + m_pFctStartAudioDec returns 0x%x", err); + return err; + } + } + + /** + * Allocate output buffer for the audio decoder */ + outputBuffer.m_bufferSize = + pClipCtxt->pAudioStream->m_byteFrameLength + * pClipCtxt->pAudioStream->m_byteSampleSize + * pClipCtxt->pAudioStream->m_nbChannels; + + if( outputBuffer.m_bufferSize > 0 ) { + + outputBuffer.m_dataAddress = + (M4OSA_MemAddr8)M4OSA_32bitAlignedMalloc(outputBuffer.m_bufferSize \ + *sizeof(short), M4VSS3GPP, (M4OSA_Char *)"outputBuffer.m_bufferSize"); + + if( M4OSA_NULL == outputBuffer.m_dataAddress ) { + + M4OSA_TRACE1_0( + "M4VSS3GPP_intCheckAndGetCodecAacProperties():\ + unable to allocate outputBuffer.m_dataAddress"); + return M4ERR_ALLOC; + } + } + + err = pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctStepAudioDec( + pClipCtxt->pAudioDecCtxt, M4OSA_NULL, &outputBuffer, M4OSA_FALSE); + + if ( err == M4WAR_INFO_FORMAT_CHANGE ) { + + // Get the properties from codec node + pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec( + pClipCtxt->pAudioDecCtxt, + M4AD_kOptionID_AudioNbChannels, (M4OSA_DataOption) &optionValue); + + pClipCtxt->AacProperties.aNumChan = optionValue; + // Reset Reader structure value also + pClipCtxt->pAudioStream->m_nbChannels = optionValue; + + pClipCtxt->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec( + pClipCtxt->pAudioDecCtxt, + M4AD_kOptionID_AudioSampFrequency, (M4OSA_DataOption) &optionValue); + + pClipCtxt->AacProperties.aSampFreq = optionValue; + // Reset Reader structure value also + pClipCtxt->pAudioStream->m_samplingFrequency = optionValue; + + } else if( err != M4NO_ERROR) { + M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties:\ + m_pFctStepAudioDec returns err = 0x%x", err); + } + + free(outputBuffer.m_dataAddress); + + // Reset the stream reader + err = pClipCtxt->ShellAPI.m_pReader->m_pFctReset( + pClipCtxt->pReaderContext, + (M4_StreamHandler *)pClipCtxt->pAudioStream); + + if (M4NO_ERROR != err) { + M4OSA_TRACE1_1("M4VSS3GPP_intCheckAndGetCodecAacProperties\ + Error in reseting reader: 0x%x", err); + } + + return err; + +} diff --git a/libvideoeditor/vss/src/M4VSS3GPP_EditAudio.c b/libvideoeditor/vss/src/M4VSS3GPP_EditAudio.c index 85b939d..746883d 100755 --- a/libvideoeditor/vss/src/M4VSS3GPP_EditAudio.c +++ b/libvideoeditor/vss/src/M4VSS3GPP_EditAudio.c @@ -229,6 +229,7 @@ M4OSA_ERR M4VSS3GPP_intEditStepMP3( M4VSS3GPP_InternalEditContext *pC ) M4OSA_ERR M4VSS3GPP_intEditStepAudio( M4VSS3GPP_InternalEditContext *pC ) { M4OSA_ERR err; + int32_t auTimeStamp = -1; M4ENCODER_AudioBuffer pEncInBuffer; /**< Encoder input buffer for api */ M4ENCODER_AudioBuffer pEncOutBuffer; /**< Encoder output buffer for api */ @@ -563,23 +564,21 @@ M4OSA_ERR M4VSS3GPP_intEditStepAudio( M4VSS3GPP_InternalEditContext *pC ) } //if(0 != pEncInBuffer.pTableBufferSize[0]) #endif + pC->pC1->pAudioFramePtr = M4OSA_NULL; - err = M4VSS3GPP_intClipReadNextAudioFrame(pC->pC1); - - M4OSA_TRACE2_3( - "F .... read : cts = %.0f + %.0f [ 0x%x ]", - pC->pC1->iAudioFrameCts / pC->pC1->scale_audio, - pC->pC1->iAoffset / pC->pC1->scale_audio, - pC->pC1->uiAudioFrameSize); + // Get timestamp of last read AU + pC->pC1->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec( + pC->pC1->pAudioDecCtxt, M4AD_kOptionID_AuCTS, + (M4OSA_DataOption) &auTimeStamp); - if( M4OSA_ERR_IS_ERROR(err) ) - { - M4OSA_TRACE1_1( - "M4VSS3GPP_intEditStepAudio: DECODE_ENCODE-prefetch:\ - M4VSS3GPP_intClipReadNextAudioFrame(b) returns 0x%x!", - err); - return err; + if (auTimeStamp == -1) { + M4OSA_TRACE1_0("M4VSS3GPP_intEditStepAudio: \ + invalid audio timestamp returned"); + return M4WAR_INVALID_TIME; } + + pC->pC1->iAudioFrameCts = auTimeStamp; + } } @@ -601,6 +600,21 @@ M4OSA_ERR M4VSS3GPP_intEditStepAudio( M4VSS3GPP_InternalEditContext *pC ) return err; } + pC->pC1->pAudioFramePtr = M4OSA_NULL; + + // Get timestamp of last read AU + pC->pC1->ShellAPI.m_pAudioDecoder->m_pFctGetOptionAudioDec( + pC->pC1->pAudioDecCtxt, M4AD_kOptionID_AuCTS, + (M4OSA_DataOption) &auTimeStamp); + + if (auTimeStamp == -1) { + M4OSA_TRACE1_0("M4VSS3GPP_intEditStepAudio: invalid audio \ + timestamp returned"); + return M4WAR_INVALID_TIME; + } + + pC->pC1->iAudioFrameCts = auTimeStamp; + /** * Apply the effect */ if( pC->iClip1ActiveEffect >= 0 ) diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp index 0227e0a..3ffdf21 100755 --- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp +++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp @@ -52,7 +52,7 @@ namespace android { struct VideoEditorAudioDecoderSource : public MediaSource { public: static sp<VideoEditorAudioDecoderSource> Create( - const sp<MetaData>& format); + const sp<MetaData>& format, void *decoderShellContext); virtual status_t start(MetaData *params = NULL); virtual status_t stop(); virtual sp<MetaData> getFormat(); @@ -73,37 +73,63 @@ struct VideoEditorAudioDecoderSource : public MediaSource { STARTED, ERROR }; - VideoEditorAudioDecoderSource(const sp<MetaData>& format); + VideoEditorAudioDecoderSource(const sp<MetaData>& format, + void *decoderShellContext); sp<MetaData> mFormat; MediaBufferChain* mFirstBufferLink; MediaBufferChain* mLastBufferLink; int32_t mNbBuffer; bool mIsEOS; State mState; - + void* mDecShellContext; // Don't call me. VideoEditorAudioDecoderSource(const VideoEditorAudioDecoderSource&); VideoEditorAudioDecoderSource& operator=( const VideoEditorAudioDecoderSource &); }; +/** + ****************************************************************************** + * structure VideoEditorAudioDecoder_Context + * @brief This structure defines the context of the StageFright audio decoder + * shell + ****************************************************************************** +*/ + +typedef struct { + M4AD_Type mDecoderType; + M4_AudioStreamHandler* mAudioStreamHandler; + sp<VideoEditorAudioDecoderSource> mDecoderSource; + OMXClient mClient; + sp<MediaSource> mDecoder; + int32_t mNbOutputChannels; + uint32_t mNbInputFrames; + uint32_t mNbOutputFrames; + M4READER_DataInterface *m_pReader; + M4_AccessUnit* m_pNextAccessUnitToDecode; + M4OSA_ERR readerErrCode; + int32_t timeStampMs; + +} VideoEditorAudioDecoder_Context; + sp<VideoEditorAudioDecoderSource> VideoEditorAudioDecoderSource::Create( - const sp<MetaData>& format) { + const sp<MetaData>& format, void *decoderShellContext) { sp<VideoEditorAudioDecoderSource> aSource = - new VideoEditorAudioDecoderSource(format); + new VideoEditorAudioDecoderSource(format, decoderShellContext); return aSource; } VideoEditorAudioDecoderSource::VideoEditorAudioDecoderSource( - const sp<MetaData>& format): + const sp<MetaData>& format, void* decoderShellContext): mFormat(format), mFirstBufferLink(NULL), mLastBufferLink(NULL), mNbBuffer(0), mIsEOS(false), - mState(CREATED) { + mState(CREATED), + mDecShellContext(decoderShellContext) { } VideoEditorAudioDecoderSource::~VideoEditorAudioDecoderSource() { @@ -168,6 +194,10 @@ status_t VideoEditorAudioDecoderSource::read(MediaBuffer **buffer, MediaSource::ReadOptions readOptions; status_t err = OK; MediaBufferChain* tmpLink = NULL; + M4OSA_ERR lerr = M4NO_ERROR; + + VideoEditorAudioDecoder_Context* pDecContext = + (VideoEditorAudioDecoder_Context *)mDecShellContext; LOGV("VideoEditorAudioDecoderSource::read begin"); @@ -178,14 +208,40 @@ status_t VideoEditorAudioDecoderSource::read(MediaBuffer **buffer, // Get a buffer from the chain if( NULL == mFirstBufferLink ) { - *buffer = NULL; - if( mIsEOS ) { + M4_AccessUnit* pAccessUnit = pDecContext->m_pNextAccessUnitToDecode; + + // Get next AU from reader. + lerr = pDecContext->m_pReader->m_pFctGetNextAu( + pDecContext->m_pReader->m_readerContext, + (M4_StreamHandler*)pDecContext->mAudioStreamHandler, + pAccessUnit); + + if (lerr == M4WAR_NO_MORE_AU) { + LOGV("VideoEditorAudioDecoderSource::getNextAU() returning err = " + "ERROR_END_OF_STREAM;"); + *buffer = NULL; LOGV("VideoEditorAudioDecoderSource::read : EOS"); + pDecContext->readerErrCode = M4WAR_NO_MORE_AU; return ERROR_END_OF_STREAM; + } + + MediaBufferChain* newLink = new MediaBufferChain; + MediaBuffer* newBuffer = new MediaBuffer((size_t)pAccessUnit->m_size); + memcpy((void *)((M4OSA_Int8*)newBuffer->data() + newBuffer->range_offset()), + (void *)pAccessUnit->m_dataAddress, pAccessUnit->m_size); + newBuffer->meta_data()->setInt64(kKeyTime, (pAccessUnit->m_CTS * 1000LL)); + + pDecContext->timeStampMs = pAccessUnit->m_CTS; + newLink->buffer = newBuffer; + newLink->nextLink = NULL; + if( NULL != mLastBufferLink ) { + mLastBufferLink->nextLink = newLink; } else { - LOGV("VideoEditorAudioDecoderSource::read : no buffer available"); - return UNKNOWN_ERROR; + mFirstBufferLink = newLink; } + mLastBufferLink = newLink; + mNbBuffer++; + } *buffer = mFirstBufferLink->buffer; @@ -203,24 +259,51 @@ status_t VideoEditorAudioDecoderSource::read(MediaBuffer **buffer, int32_t VideoEditorAudioDecoderSource::storeBuffer(MediaBuffer *buffer) { status_t err = OK; + M4OSA_ERR lerr = M4NO_ERROR; + MediaBufferChain* newLink = new MediaBufferChain; + + VideoEditorAudioDecoder_Context* pDecContext = + (VideoEditorAudioDecoder_Context *)mDecShellContext; LOGV("VideoEditorAudioDecoderSource::storeBuffer begin"); - // A NULL input buffer means that the end of stream was reached if( NULL == buffer ) { - mIsEOS = true; + M4_AccessUnit* pAccessUnit = pDecContext->m_pNextAccessUnitToDecode; + // Get next AU from reader. + lerr = pDecContext->m_pReader->m_pFctGetNextAu( + pDecContext->m_pReader->m_readerContext, + (M4_StreamHandler*)pDecContext->mAudioStreamHandler, + pAccessUnit); + + if (lerr == M4WAR_NO_MORE_AU) { + LOGV("VideoEditorAudioDecoderSource::getNextAU() returning err = " + "ERROR_END_OF_STREAM;"); + pDecContext->readerErrCode = M4WAR_NO_MORE_AU; + delete newLink; + return mNbBuffer; + } + + MediaBuffer* newBuffer = new MediaBuffer((size_t)pAccessUnit->m_size); + memcpy((void *)((M4OSA_Int8*)newBuffer->data() + newBuffer->range_offset()), + (void *)pAccessUnit->m_dataAddress, pAccessUnit->m_size); + newBuffer->meta_data()->setInt64(kKeyTime, (pAccessUnit->m_CTS * 1000LL)); + + pDecContext->timeStampMs = pAccessUnit->m_CTS; + newLink->buffer = newBuffer; + } else { - MediaBufferChain* newLink = new MediaBufferChain; + LOGV("VideoEditorAudioDecoderSource::storeBuffer else case"); newLink->buffer = buffer; - newLink->nextLink = NULL; - if( NULL != mLastBufferLink ) { - mLastBufferLink->nextLink = newLink; - } else { - mFirstBufferLink = newLink; - } - mLastBufferLink = newLink; - mNbBuffer++; } + newLink->nextLink = NULL; + if( NULL != mLastBufferLink ) { + mLastBufferLink->nextLink = newLink; + } else { + mFirstBufferLink = newLink; + } + mLastBufferLink = newLink; + mNbBuffer++; + LOGV("VideoEditorAudioDecoderSource::storeBuffer END"); return mNbBuffer; } @@ -353,24 +436,6 @@ cleanUp: * ENGINE INTERFACE * ********************/ -/** - ****************************************************************************** - * structure VideoEditorAudioDecoder_Context - * @brief This structure defines the context of the StageFright audio decoder - * shell - ****************************************************************************** -*/ -typedef struct { - M4AD_Type mDecoderType; - M4_AudioStreamHandler* mAudioStreamHandler; - sp<VideoEditorAudioDecoderSource> mDecoderSource; - OMXClient mClient; - sp<MediaSource> mDecoder; - int32_t mNbOutputChannels; - uint32_t mNbInputFrames; - uint32_t mNbOutputFrames; -} VideoEditorAudioDecoder_Context; - M4OSA_ERR VideoEditorAudioDecoder_destroy(M4AD_Context pContext) { M4OSA_ERR err = M4NO_ERROR; VideoEditorAudioDecoder_Context* pDecoderContext = M4OSA_NULL; @@ -430,6 +495,8 @@ M4OSA_ERR VideoEditorAudioDecoder_create(M4AD_Type decoderType, pDecoderContext->mNbInputFrames = 0; pDecoderContext->mNbOutputFrames = 0; + pDecoderContext->readerErrCode = M4NO_ERROR; + pDecoderContext->timeStampMs = -1; LOGV("VideoEditorAudioDecoder_create : maxAUSize %d", pDecoderContext->mAudioStreamHandler->m_basicProperties.m_maxAUSize); @@ -518,7 +585,7 @@ M4OSA_ERR VideoEditorAudioDecoder_create(M4AD_Type decoderType, // Create the decoder source pDecoderContext->mDecoderSource = VideoEditorAudioDecoderSource::Create( - decoderMetaData); + decoderMetaData, (void *)pDecoderContext); VIDEOEDITOR_CHECK(NULL != pDecoderContext->mDecoderSource.get(), M4ERR_STATE); @@ -709,11 +776,32 @@ M4OSA_ERR VideoEditorAudioDecoder_step(M4AD_Context pContext, // Read result = pDecoderContext->mDecoder->read(&outputBuffer, NULL); - if(OK != result) { - LOGE("VideoEditorAudioDecoder_step result = %d",result); - + if (INFO_FORMAT_CHANGED == result) { + LOGV("VideoEditorAudioDecoder_step: Audio decoder \ + returned INFO_FORMAT_CHANGED"); + CHECK(outputBuffer == NULL); + sp<MetaData> meta = pDecoderContext->mDecoder->getFormat(); + int32_t sampleRate, channelCount; + + CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); + CHECK(meta->findInt32(kKeyChannelCount, &channelCount)); + LOGV("VideoEditorAudioDecoder_step: samplingFreq = %d", sampleRate); + LOGV("VideoEditorAudioDecoder_step: channelCnt = %d", channelCount); + pDecoderContext->mAudioStreamHandler->m_samplingFrequency = + (uint32_t)sampleRate; + pDecoderContext->mAudioStreamHandler->m_nbChannels = + (uint32_t)channelCount; + pDecoderContext->mNbOutputChannels = channelCount; + + return M4WAR_INFO_FORMAT_CHANGE; + } else if (ERROR_END_OF_STREAM == result) { + LOGV("VideoEditorAudioDecoder_step: Audio decoder \ + returned ERROR_END_OF_STREAM"); + pDecoderContext->readerErrCode = M4WAR_NO_MORE_AU; + return M4WAR_NO_MORE_AU; + } else if (OK != result) { + return M4ERR_STATE; } - VIDEOEDITOR_CHECK(OK == result, M4ERR_STATE); // Convert the PCM buffer err = VideoEditorAudioDecoder_processOutputBuffer(pDecoderContext, @@ -769,6 +857,19 @@ M4OSA_ERR VideoEditorAudioDecoder_setOption(M4AD_Context pContext, LOGV("VideoEditorAudioDecodersetOption UserParam is not supported"); err = M4ERR_NOT_IMPLEMENTED; break; + + case M4AD_kOptionID_3gpReaderInterface: + LOGV("VideoEditorAudioDecodersetOption 3gpReaderInterface"); + pDecoderContext->m_pReader = + (M4READER_DataInterface *)optionValue; + break; + + case M4AD_kOptionID_AudioAU: + LOGV("VideoEditorAudioDecodersetOption AudioAU"); + pDecoderContext->m_pNextAccessUnitToDecode = + (M4_AccessUnit *)optionValue; + break; + default: LOGV("VideoEditorAudioDecoder_setOption unsupported optionId 0x%X", optionID); @@ -799,6 +900,25 @@ M4OSA_ERR VideoEditorAudioDecoder_getOption(M4AD_Context pContext, pDecoderContext = (VideoEditorAudioDecoder_Context*)pContext; switch( optionID ) { + + case M4AD_kOptionID_GetAudioAUErrCode: + *(uint32_t *)optionValue = pDecoderContext->readerErrCode; + break; + + case M4AD_kOptionID_AudioNbChannels: + *(uint32_t *)optionValue = + pDecoderContext->mAudioStreamHandler->m_nbChannels; + break; + + case M4AD_kOptionID_AudioSampFrequency: + *(uint32_t *)optionValue = + pDecoderContext->mAudioStreamHandler->m_samplingFrequency; + break; + + case M4AD_kOptionID_AuCTS: + *(uint32_t *)optionValue = pDecoderContext->timeStampMs; + break; + default: LOGV("VideoEditorAudioDecoder_getOption unsupported optionId 0x%X", optionID); |