#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/ACodec.h>
#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/OMXCodec.h>
#include <OMX_AudioExt.h>
#include <OMX_IndexExt.h>
def.nBufferSize = 1000000; // dts!
} else {
// max aggregated buffer size from nuplayer
- def.nBufferSize = 24 * 1024;
+ def.nBufferSize = 32 * 1024;
}
def.bEnabled = OMX_TRUE;
if (mCodecAlreadyOpened) {
avcodec_close(mCtx);
- av_free(mCtx);
- mCtx = NULL;
+ mCodecAlreadyOpened = false;
}
+ av_free(mCtx);
+ mCtx = NULL;
}
if (mFrame) {
- av_freep(&mFrame);
+ av_frame_free(&mFrame);
mFrame = NULL;
}
if (mSwrCtx) {
profile->eEndian = OMX_EndianBig;
profile->bInterleaved = OMX_TRUE;
profile->ePCMMode = OMX_AUDIO_PCMModeLinear;
+ profile->nBitPerSample = 32;
+ profile->eNumData = OMX_NumericalDataFloat;
if (isConfigured()) {
- AVSampleFormat packed = av_get_packed_sample_fmt(mAudioTgtFmt);
- if (packed == AV_SAMPLE_FMT_U8)
- profile->nBitPerSample = 8;
- else if (packed == AV_SAMPLE_FMT_S16)
- profile->nBitPerSample = 16;
- else if (packed == AV_SAMPLE_FMT_S32)
- profile->nBitPerSample = 24;
- else
- profile->nBitPerSample = av_get_bytes_per_sample(mAudioTgtFmt) * 8;
- } else {
- profile->nBitPerSample = 32;
+ switch (av_get_packed_sample_fmt(mAudioTgtFmt)) {
+ case AV_SAMPLE_FMT_U8:
+ profile->nBitPerSample = 8;
+ profile->eNumData = OMX_NumericalDataUnsigned;
+ break;
+ case AV_SAMPLE_FMT_S16:
+ profile->nBitPerSample = 16;
+ profile->eNumData = OMX_NumericalDataSigned;
+ break;
+ case AV_SAMPLE_FMT_S32:
+ profile->nBitPerSample = 32;
+ profile->eNumData = OMX_NumericalDataSigned;
+ break;
+ default:
+ profile->nBitPerSample = 32;
+ profile->eNumData = OMX_NumericalDataFloat;
+ break;
+ }
}
- if (getOMXChannelMapping(mAudioTgtChannels, profile->eChannelMapping) != OK) {
+ if (ACodec::getOMXChannelMapping(mAudioTgtChannels, profile->eChannelMapping) != OK) {
return OMX_ErrorNone;
}
profile->nSamplingRate = mAudioTgtFreq;
//mCtx has been updated(adjustAudioParams)!
- ALOGV("get pcm params, nChannels:%lu, nSamplingRate:%lu, nBitsPerSample:%lu",
+ ALOGV("get pcm params, nChannels:%u, nSamplingRate:%u, nBitPerSample:%u",
profile->nChannels, profile->nSamplingRate, profile->nBitPerSample);
return OMX_ErrorNone;
profile->nChannels = mCtx->channels;
profile->nSampleRate = mCtx->sample_rate;
-
+ profile->nCompressionLevel = mCtx->bits_per_raw_sample;
return OMX_ErrorNone;
}
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioAlac:
+ {
+ OMX_AUDIO_PARAM_ALACTYPE *profile =
+ (OMX_AUDIO_PARAM_ALACTYPE *)params;
+
+ if (profile->nPortIndex != kInputPortIndex) {
+ return OMX_ErrorUndefined;
+ }
+
+ profile->nChannels = mCtx->channels;
+ profile->nSamplingRate = mCtx->sample_rate;
+
+ profile->nBitsPerSample = mCtx->bits_per_coded_sample;
+
+ return OMX_ErrorNone;
+ }
+
case OMX_IndexParamAudioApe:
{
OMX_AUDIO_PARAM_APETYPE *profile =
void SoftFFmpegAudio::adjustAudioParams() {
- uint32_t max_rate = 192000;
-
mReconfiguring = isConfigured();
// let android audio mixer to downmix if there is no multichannel output
// and use number of channels from the source file, useful for HDMI/offload output
mAudioTgtChannels = mCtx->channels;
- mAudioTgtFreq = FFMIN(max_rate, FFMAX(8000, mCtx->sample_rate));
+ mAudioTgtFreq = FFMIN(192000, FFMAX(8000, mCtx->sample_rate));
mAudioTgtChannels = mCtx->channels;
mAudioTgtFreq = mCtx->sample_rate;
return OMX_ErrorUndefined;
}
- if (profile->nBitPerSample == 24) {
- mAudioTgtFmt = AV_SAMPLE_FMT_S32;
- } else if (profile->nBitPerSample == 32) {
- mAudioTgtFmt = AV_SAMPLE_FMT_FLT;
- } else if (profile->nBitPerSample == 8) {
- mAudioTgtFmt = AV_SAMPLE_FMT_U8;
- } else {
- mAudioTgtFmt = AV_SAMPLE_FMT_S16;
+ switch (profile->nBitPerSample) {
+ case 8:
+ mAudioTgtFmt = AV_SAMPLE_FMT_U8;
+ break;
+ case 16:
+ mAudioTgtFmt = AV_SAMPLE_FMT_S16;
+ break;
+ case 24:
+ mAudioTgtFmt = AV_SAMPLE_FMT_S32;
+ break;
+ case 32:
+ if (profile->eNumData == OMX_NumericalDataFloat) {
+ mAudioTgtFmt = AV_SAMPLE_FMT_FLT;
+ break;
+ }
+ mAudioTgtFmt = AV_SAMPLE_FMT_S32;
+ break;
+ default:
+ ALOGE("Unknown PCM encoding, assuming floating point");
+ mAudioTgtFmt = AV_SAMPLE_FMT_FLT;
}
mAudioTgtFreq = profile->nSamplingRate;
mAudioTgtChannels = profile->nChannels;
- ALOGV("set OMX_IndexParamAudioPcm, nChannels:%lu, "
- "nSampleRate:%lu, nBitsPerSample:%lu",
+ ALOGV("set OMX_IndexParamAudioPcm, nChannels:%u, "
+ "nSampleRate:%u, nBitPerSample:%u",
profile->nChannels, profile->nSamplingRate,
profile->nBitPerSample);
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioAac, nChannels:%lu, nSampleRate:%lu",
+ ALOGV("set OMX_IndexParamAudioAac, nChannels:%u, nSampleRate:%u",
profile->nChannels, profile->nSampleRate);
return OMX_ErrorNone;
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioMp3, nChannels:%lu, nSampleRate:%lu",
+ ALOGV("set OMX_IndexParamAudioMp3, nChannels:%u, nSampleRate:%u",
profile->nChannels, profile->nSampleRate);
return OMX_ErrorNone;
adjustAudioParams();
ALOGD("set OMX_IndexParamAudioVorbis, "
- "nChannels=%lu, nSampleRate=%lu, nBitRate=%lu, "
- "nMinBitRate=%lu, nMaxBitRate=%lu",
+ "nChannels=%u, nSampleRate=%u, nBitRate=%u, "
+ "nMinBitRate=%u, nMaxBitRate=%u",
profile->nChannels, profile->nSampleRate,
profile->nBitRate, profile->nMinBitRate,
profile->nMaxBitRate);
adjustAudioParams();
ALOGV("set OMX_IndexParamAudioWma, nChannels:%u, "
- "nSampleRate:%lu, nBitRate:%lu, nBlockAlign:%u",
+ "nSampleRate:%u, nBitRate:%u, nBlockAlign:%u",
profile->nChannels, profile->nSamplingRate,
profile->nBitRate, profile->nBlockAlign);
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioRa, nChannels:%lu, "
- "nSampleRate:%lu, nBlockAlign:%d",
+ ALOGV("set OMX_IndexParamAudioRa, nChannels:%u, "
+ "nSampleRate:%u, nBlockAlign:%d",
profile->nChannels, profile->nSamplingRate, mCtx->block_align);
return OMX_ErrorNone;
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioFlac, nChannels:%lu, nSampleRate:%lu ",
+ ALOGV("set OMX_IndexParamAudioFlac, nChannels:%u, nSampleRate:%u ",
profile->nChannels, profile->nSampleRate);
return OMX_ErrorNone;
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioMp2, nChannels:%lu, nSampleRate:%lu",
+ ALOGV("set OMX_IndexParamAudioMp2, nChannels:%u, nSampleRate:%u",
profile->nChannels, profile->nSampleRate);
return OMX_ErrorNone;
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioAc3, nChannels:%lu, nSampleRate:%lu",
+ ALOGV("set OMX_IndexParamAudioAc3, nChannels:%u, nSampleRate:%u",
profile->nChannels, profile->nSamplingRate);
return OMX_ErrorNone;
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioAndroidAc3, nChannels:%lu, nSampleRate:%lu",
+ ALOGV("set OMX_IndexParamAudioAndroidAc3, nChannels:%u, nSampleRate:%u",
profile->nChannels, profile->nSampleRate);
return OMX_ErrorNone;
}
+ case OMX_IndexParamAudioAlac:
+ {
+ OMX_AUDIO_PARAM_ALACTYPE *profile =
+ (OMX_AUDIO_PARAM_ALACTYPE *)params;
+
+ if (profile->nPortIndex != kInputPortIndex) {
+ return OMX_ErrorUndefined;
+ }
+
+ mCtx->channels = profile->nChannels;
+ mCtx->sample_rate = profile->nSamplingRate;
+ mCtx->bits_per_coded_sample = profile->nBitsPerSample;
+
+ adjustAudioParams();
+
+ ALOGV("set OMX_IndexParamAudioAlac, nChannels:%u, "
+ "nSampleRate:%u, nBitsPerSample:%u",
+ profile->nChannels, profile->nSamplingRate,
+ profile->nBitsPerSample);
+
+ return OMX_ErrorNone;
+ }
case OMX_IndexParamAudioApe:
{
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioApe, nChannels:%lu, "
- "nSampleRate:%lu, nBitsPerSample:%lu",
+ ALOGV("set OMX_IndexParamAudioApe, nChannels:%u, "
+ "nSampleRate:%u, nBitsPerSample:%u",
profile->nChannels, profile->nSamplingRate,
profile->nBitsPerSample);
adjustAudioParams();
- ALOGV("set OMX_IndexParamAudioDts, nChannels:%lu, nSampleRate:%lu",
+ ALOGV("set OMX_IndexParamAudioDts, nChannels:%u, nSampleRate:%u",
profile->nChannels, profile->nSamplingRate);
return OMX_ErrorNone;
adjustAudioParams();
ALOGD("set OMX_IndexParamAudioFFmpeg, "
- "eCodecId:%ld(%s), nChannels:%lu, nBitRate:%lu, "
- "nBitsPerSample:%lu, nSampleRate:%lu, "
- "nBlockAlign:%lu, eSampleFormat:%lu(%s)",
+ "eCodecId:%d(%s), nChannels:%u, nBitRate:%u, "
+ "nBitsPerSample:%u, nSampleRate:%u, "
+ "nBlockAlign:%u, eSampleFormat:%u(%s)",
profile->eCodecId, avcodec_get_name(mCtx->codec_id),
profile->nChannels, profile->nBitRate,
profile->nBitsPerSample, profile->nSampleRate,
BufferInfo *inInfo = *inQueue.begin();
OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
- ALOGI("got extradata, ignore: %d, size: %lu",
+ ALOGI("got extradata, ignore: %d, size: %u",
mIgnoreExtradata, inHeader->nFilledLen);
hexdump(inHeader->pBuffer + inHeader->nOffset, inHeader->nFilledLen);
if (mIgnoreExtradata) {
- ALOGI("got extradata, size: %lu, but ignore it", inHeader->nFilledLen);
+ ALOGI("got extradata, size: %u, but ignore it", inHeader->nFilledLen);
} else {
if (!mExtradataReady) {
uint32_t ret = ERR_OK;
int gotFrm = false;
int32_t ret = ERR_OK;
int32_t inputBufferUsedLength = 0;
- bool is_flush = (mEOSStatus != INPUT_DATA_AVAILABLE);
+ bool is_flush = (mEOSStatus == OUTPUT_FRAMES_FLUSHED);
List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
BufferInfo *inInfo = NULL;
OMX_BUFFERHEADERTYPE *inHeader = NULL;
CHECK_EQ(mResampledDataSize, 0);
- if (!is_flush) {
+ if (!is_flush && !inQueue.empty()) {
inInfo = *inQueue.begin();
- CHECK(inInfo != NULL);
- inHeader = inInfo->mHeader;
+ if (inInfo != NULL) {
+ inHeader = inInfo->mHeader;
- if (mInputBufferSize == 0) {
- updateTimeStamp(inHeader);
- mInputBufferSize = inHeader->nFilledLen;
+ if (mInputBufferSize == 0) {
+ updateTimeStamp(inHeader);
+ mInputBufferSize = inHeader->nFilledLen;
+ }
}
}
+ if (mEOSStatus == INPUT_EOS_SEEN && (!inHeader || inHeader->nFilledLen == 0)
+ && !(mCtx->codec->capabilities & CODEC_CAP_DELAY)) {
+ return ERR_FLUSHED;
+ }
+
AVPacket pkt;
initPacket(&pkt, inHeader);
av_frame_unref(mFrame);
len = avcodec_decode_audio4(mCtx, mFrame, &gotFrm, &pkt);
+ av_packet_unref(&pkt);
+
//a negative error code is returned if an error occurred during decoding
if (len < 0) {
ALOGW("ffmpeg audio decoder err, we skip the frame and play silence instead");
} else {
inputBufferUsedLength = len;
}
-
- CHECK_GE(inHeader->nFilledLen, inputBufferUsedLength);
- inHeader->nOffset += inputBufferUsedLength;
- inHeader->nFilledLen -= inputBufferUsedLength;
mInputBufferSize -= inputBufferUsedLength;
- if (inHeader->nFilledLen == 0) {
- CHECK_EQ(mInputBufferSize, 0);
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
+ if (inHeader != NULL) {
+ CHECK_GE(inHeader->nFilledLen, inputBufferUsedLength);
+ inHeader->nOffset += inputBufferUsedLength;
+ inHeader->nFilledLen -= inputBufferUsedLength;
+
+ if (inHeader->nFilledLen == 0) {
+ CHECK_EQ(mInputBufferSize, 0);
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+ }
}
}
return;
}
- if(!(mCtx->codec->capabilities & CODEC_CAP_DELAY)) {
- drainEOSOutputBuffer();
- mEOSStatus = OUTPUT_FRAMES_FLUSHED;
- return;
- }
-
while (!outQueue.empty()) {
if (mResampledDataSize == 0) {
int32_t err = decodeAudio();
inHeader = inInfo->mHeader;
if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
- ALOGD("ffmpeg audio decoder empty eos inbuf");
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
+ ALOGD("ffmpeg audio decoder eos");
mEOSStatus = INPUT_EOS_SEEN;
continue;
}
}
void SoftFFmpegAudio::onPortFlushCompleted(OMX_U32 portIndex) {
- ALOGV("ffmpeg audio decoder flush port(%lu)", portIndex);
+ ALOGV("ffmpeg audio decoder flush port(%u)", portIndex);
if (portIndex == kInputPortIndex) {
- if (mCtx && mCtx->codec) {
+ if (mCtx && avcodec_is_open(mCtx)) {
//Make sure that the next buffer output does not still
//depend on fragments from the last one decoded.
avcodec_flush_buffers(mCtx);
sAudioClock = (int64_t*) malloc(sizeof(int64_t));
*sAudioClock = 0;
}
- ALOGV("getAudioClock: %lld", *sAudioClock);
+ ALOGV("getAudioClock: %" PRId64, *sAudioClock);
return *sAudioClock;
}
initDecoder(codecID);
mSignalledError = false;
mOutputPortSettingsChange = NONE;
+ mEOSStatus = INPUT_DATA_AVAILABLE;
}
SoftOMXComponent* SoftFFmpegAudio::createSoftOMXComponent(