#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>
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:%u, nSamplingRate:%u, nBitsPerSample:%u",
+ 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 =
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:%u, "
- "nSampleRate:%u, nBitsPerSample:%u",
+ "nSampleRate:%u, nBitPerSample:%u",
profile->nChannels, profile->nSamplingRate,
profile->nBitPerSample);
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:
{
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;
}
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(