summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/ACodec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/ACodec.cpp')
-rw-r--r--media/libstagefright/ACodec.cpp168
1 files changed, 145 insertions, 23 deletions
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 18d221b..a01c63a 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -44,6 +44,8 @@
#include <media/stagefright/OMXCodec.h>
#include <media/stagefright/PersistentSurface.h>
#include <media/stagefright/SurfaceUtils.h>
+#include <media/stagefright/FFMPEGSoftCodec.h>
+
#include <media/hardware/HardwareAPI.h>
#include <OMX_AudioExt.h>
@@ -541,7 +543,12 @@ ACodec::ACodec()
ACodec::~ACodec() {
}
-status_t ACodec::setupCustomCodec(status_t err, const char *, const sp<AMessage> &) {
+status_t ACodec::setupCustomCodec(status_t err, const char *mime, const sp<AMessage> &msg) {
+ if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11) && !mIsEncoder) {
+ return FFMPEGSoftCodec::setAudioFormat(
+ msg, mime, mOMX, mNode);
+ }
+
return err;
}
@@ -1589,7 +1596,11 @@ status_t ACodec::setComponentRole(
}
if (i == kNumMimeToRole) {
- return ERROR_UNSUPPORTED;
+ status_t err = ERROR_UNSUPPORTED;
+ if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
+ err = FFMPEGSoftCodec::setSupportedRole(mOMX, mNode, isEncoder, mime);
+ }
+ return err;
}
const char *role =
@@ -1910,7 +1921,8 @@ status_t ACodec::configureCodec(
if (video) {
// determine need for software renderer
bool usingSwRenderer = false;
- if (haveNativeWindow && mComponentName.startsWith("OMX.google.")) {
+ if (haveNativeWindow && (mComponentName.startsWith("OMX.google.") ||
+ mComponentName.startsWith("OMX.ffmpeg."))) {
usingSwRenderer = true;
haveNativeWindow = false;
}
@@ -1995,10 +2007,12 @@ status_t ACodec::configureCodec(
// and have the decoder figure it all out.
err = OK;
} else {
+ int32_t bitsPerSample = 16;
+ msg->findInt32("bit-width", &bitsPerSample);
err = setupRawAudioFormat(
encoder ? kPortIndexInput : kPortIndexOutput,
sampleRate,
- numChannels);
+ numChannels, bitsPerSample);
}
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
int32_t numChannels, sampleRate;
@@ -2073,11 +2087,7 @@ status_t ACodec::configureCodec(
}
err = setupG711Codec(encoder, sampleRate, numChannels);
}
-#ifdef QTI_FLAC_DECODER
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC) && encoder) {
-#else
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
-#endif
int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
if (encoder &&
(!msg->findInt32("channel-count", &numChannels)
@@ -2113,16 +2123,21 @@ status_t ACodec::configureCodec(
|| !msg->findInt32("sample-rate", &sampleRate)) {
err = INVALID_OPERATION;
} else {
- err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
+ int32_t bitsPerSample = 16;
+ msg->findInt32("bit-width", &bitsPerSample);
+ err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, bitsPerSample);
}
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
+ } else if (!strncmp(mComponentName.c_str(), "OMX.google.", 11)
+ && !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
int32_t numChannels;
int32_t sampleRate;
if (!msg->findInt32("channel-count", &numChannels)
|| !msg->findInt32("sample-rate", &sampleRate)) {
err = INVALID_OPERATION;
} else {
- err = setupAC3Codec(encoder, numChannels, sampleRate);
+ int32_t bitsPerSample = 16;
+ msg->findInt32("bit-width", &bitsPerSample);
+ err = setupAC3Codec(encoder, numChannels, sampleRate, bitsPerSample);
}
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_EAC3)) {
int32_t numChannels;
@@ -2131,7 +2146,9 @@ status_t ACodec::configureCodec(
|| !msg->findInt32("sample-rate", &sampleRate)) {
err = INVALID_OPERATION;
} else {
- err = setupEAC3Codec(encoder, numChannels, sampleRate);
+ int32_t bitsPerSample = 16;
+ msg->findInt32("bit-width", &bitsPerSample);
+ err = setupEAC3Codec(encoder, numChannels, sampleRate, bitsPerSample);
}
} else {
err = setupCustomCodec(err, mime, msg);
@@ -2448,9 +2465,9 @@ status_t ACodec::setupAACCodec(
}
status_t ACodec::setupAC3Codec(
- bool encoder, int32_t numChannels, int32_t sampleRate) {
+ bool encoder, int32_t numChannels, int32_t sampleRate, int32_t bitsPerSample) {
status_t err = setupRawAudioFormat(
- encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
+ encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels, bitsPerSample);
if (err != OK) {
return err;
@@ -2486,9 +2503,9 @@ status_t ACodec::setupAC3Codec(
}
status_t ACodec::setupEAC3Codec(
- bool encoder, int32_t numChannels, int32_t sampleRate) {
+ bool encoder, int32_t numChannels, int32_t sampleRate, int32_t bitsPerSample) {
status_t err = setupRawAudioFormat(
- encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels);
+ encoder ? kPortIndexInput : kPortIndexOutput, sampleRate, numChannels, bitsPerSample);
if (err != OK) {
return err;
@@ -2634,7 +2651,7 @@ status_t ACodec::setupFlacCodec(
}
status_t ACodec::setupRawAudioFormat(
- OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
+ OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, int32_t bitsPerSample) {
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = portIndex;
@@ -2669,7 +2686,7 @@ status_t ACodec::setupRawAudioFormat(
pcmParams.nChannels = numChannels;
pcmParams.eNumData = OMX_NumericalDataSigned;
pcmParams.bInterleaved = OMX_TRUE;
- pcmParams.nBitPerSample = 16;
+ pcmParams.nBitPerSample = bitsPerSample;
pcmParams.nSamplingRate = sampleRate;
pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
@@ -2896,7 +2913,13 @@ status_t ACodec::setupVideoDecoder(
status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
if (err != OK) {
- return err;
+ if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
+ err = FFMPEGSoftCodec::setVideoFormat(
+ msg, mime, mOMX, mNode, mIsEncoder, &compressionFormat);
+ }
+ if (err != OK) {
+ return err;
+ }
}
err = setVideoPortFormatType(
@@ -3046,7 +3069,14 @@ status_t ACodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
if (err != OK) {
- return err;
+ if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
+ err = FFMPEGSoftCodec::setVideoFormat(
+ msg, mime, mOMX, mNode, mIsEncoder, &compressionFormat);
+ }
+ if (err != OK) {
+ ALOGE("Not a supported video mime type: %s", mime);
+ return err;
+ }
}
err = setVideoPortFormatType(
@@ -4154,6 +4184,14 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
default:
{
+ if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
+ err = FFMPEGSoftCodec::getVideoPortFormat(portIndex,
+ (int)videoDef->eCompressionFormat, notify, mOMX, mNode);
+ }
+ if (err == OK) {
+ break;
+ }
+
if (mIsEncoder ^ (portIndex == kPortIndexOutput)) {
// should be CodingUnused
ALOGE("Raw port video compression format is %s(%d)",
@@ -4200,7 +4238,9 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
if (params.nChannels <= 0
|| (params.nChannels != 1 && !params.bInterleaved)
|| (params.nBitPerSample != 16u
- && params.nBitPerSample != 24u)// we support 16/24 bit s/w decoding
+ && params.nBitPerSample != 24u
+ && params.nBitPerSample != 32u
+ && params.nBitPerSample != 8u)// we support 8/16/24/32 bit s/w decoding
|| params.eNumData != OMX_NumericalDataSigned
|| params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
@@ -4216,6 +4256,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
notify->setInt32("channel-count", params.nChannels);
notify->setInt32("sample-rate", params.nSamplingRate);
notify->setInt32("bit-width", params.nBitPerSample);
+
if (mChannelMaskPresent) {
notify->setInt32("channel-mask", mChannelMask);
}
@@ -4265,6 +4306,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
case OMX_AUDIO_CodingFLAC:
{
+ if (portIndex == kPortIndexInput) {
OMX_AUDIO_PARAM_FLACTYPE params;
InitOMXParams(&params);
params.nPortIndex = portIndex;
@@ -4279,6 +4321,7 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
notify->setInt32("channel-count", params.nChannels);
notify->setInt32("sample-rate", params.nSampleRate);
break;
+ }
}
case OMX_AUDIO_CodingMP3:
@@ -4419,6 +4462,14 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp<AMessage> &notify) {
}
default:
+ if (!strncmp(mComponentName.c_str(), "OMX.ffmpeg.", 11)) {
+ err = FFMPEGSoftCodec::getAudioPortFormat(portIndex,
+ (int)audioDef->eEncoding, notify, mOMX, mNode);
+ }
+ if (err == OK) {
+ break;
+ }
+
ALOGE("Unsupported audio coding: %s(%d)\n",
asString(audioDef->eEncoding), audioDef->eEncoding);
return BAD_TYPE;
@@ -5718,8 +5769,79 @@ bool ACodec::LoadedState::onConfigureComponent(
ALOGE("[%s] configureCodec returning error %d",
mCodec->mComponentName.c_str(), err);
- mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
- return false;
+ int32_t encoder;
+ if (!msg->findInt32("encoder", &encoder)) {
+ encoder = false;
+ }
+
+ if (!encoder && !strncmp(mime.c_str(), "video/", strlen("video/"))) {
+ Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
+
+ OMXCodec::findMatchingCodecs(
+ mime.c_str(),
+ encoder, // createEncoder
+ NULL, // matchComponentName
+ 0, // flags
+ &matchingCodecs);
+
+ status_t err = mCodec->mOMX->freeNode(mCodec->mNode);
+
+ if (err != OK) {
+ ALOGE("Failed to freeNode");
+ mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
+ return false;
+ }
+
+ mCodec->mNode = 0;
+ AString componentName;
+ sp<CodecObserver> observer = new CodecObserver;
+
+ err = NAME_NOT_FOUND;
+ for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
+ ++matchIndex) {
+ componentName = matchingCodecs.itemAt(matchIndex).mName.string();
+ if (!strcmp(mCodec->mComponentName.c_str(), componentName.c_str())) {
+ continue;
+ }
+
+ pid_t tid = gettid();
+ int prevPriority = androidGetThreadPriority(tid);
+ androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
+ err = mCodec->mOMX->allocateNode(componentName.c_str(), observer, &mCodec->mNode);
+ androidSetThreadPriority(tid, prevPriority);
+
+ if (err == OK) {
+ break;
+ } else {
+ ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str());
+ }
+
+ mCodec->mNode = 0;
+ }
+
+ if (mCodec->mNode == 0) {
+ if (!mime.empty()) {
+ ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.",
+ encoder ? "en" : "de", mime.c_str(), err);
+ } else {
+ ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err);
+ }
+
+ mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
+ return false;
+ }
+
+ sp<AMessage> notify = new AMessage(kWhatOMXMessageList, mCodec);
+ observer->setNotificationMessage(notify);
+ mCodec->mComponentName = componentName;
+
+ err = mCodec->configureCodec(mime.c_str(), msg);
+
+ if (err != OK) {
+ mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err));
+ return false;
+ }
+ }
}
{