Loading media/libmedia/MediaCodecInfo.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -141,6 +141,10 @@ bool MediaCodecInfo::isEncoder() const { return mIsEncoder; } uint32_t MediaCodecInfo::rank() const { return mRank; } void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const { mimes->clear(); for (size_t ix = 0; ix < mCaps.size(); ix++) { Loading Loading @@ -170,10 +174,12 @@ sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) { AString name = AString::FromParcel(parcel); AString owner = AString::FromParcel(parcel); bool isEncoder = static_cast<bool>(parcel.readInt32()); uint32_t rank = parcel.readUint32(); sp<MediaCodecInfo> info = new MediaCodecInfo; info->mName = name; info->mOwner = owner; info->mIsEncoder = isEncoder; info->mRank = rank; size_t size = static_cast<size_t>(parcel.readInt32()); for (size_t i = 0; i < size; i++) { AString mime = AString::FromParcel(parcel); Loading @@ -191,6 +197,7 @@ status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const { mName.writeToParcel(parcel); mOwner.writeToParcel(parcel); parcel->writeInt32(mIsEncoder); parcel->writeUint32(mRank); parcel->writeInt32(mCaps.size()); for (size_t i = 0; i < mCaps.size(); i++) { mCaps.keyAt(i).writeToParcel(parcel); Loading @@ -210,7 +217,7 @@ ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const { return -1; } MediaCodecInfo::MediaCodecInfo() { MediaCodecInfo::MediaCodecInfo() : mRank(0x100) { } void MediaCodecInfoWriter::setName(const char* name) { Loading @@ -225,6 +232,10 @@ void MediaCodecInfoWriter::setEncoder(bool isEncoder) { mInfo->mIsEncoder = isEncoder; } void MediaCodecInfoWriter::setRank(uint32_t rank) { mInfo->mRank = rank; } std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> MediaCodecInfoWriter::addMime(const char *mime) { ssize_t ix = mInfo->getCapabilityIndex(mime); Loading media/libmedia/include/media/MediaCodecInfo.h +9 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ struct MediaCodecInfo : public RefBase { * Currently, this is the "instance name" of the IOmx service. */ const char *getOwnerName() const; uint32_t rank() const; /** * Serialization over Binder Loading @@ -182,6 +183,7 @@ private: AString mOwner; bool mIsEncoder; KeyedVector<AString, sp<Capabilities> > mCaps; uint32_t mRank; ssize_t getCapabilityIndex(const char *mime) const; Loading Loading @@ -252,6 +254,13 @@ struct MediaCodecInfoWriter { * @return `true` if `mime` is removed; `false` if `mime` is not found. */ bool removeMime(const char* mime); /** * Set rank of the codec. MediaCodecList will stable-sort the list according * to rank in non-descending order. * * @param rank The rank of the component. */ void setRank(uint32_t rank); private: /** * The associated `MediaCodecInfo`. Loading media/libstagefright/ACodec.cpp +38 −74 Original line number Diff line number Diff line Loading @@ -6349,11 +6349,9 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { Vector<AString> matchingCodecs; Vector<AString> owners; AString mime; AString componentName; int32_t encoder = false; if (msg->findString("componentName", &componentName)) { CHECK(msg->findString("componentName", &componentName)); sp<IMediaCodecList> list = MediaCodecList::getInstance(); if (list == nullptr) { ALOGE("Unable to obtain MediaCodecList while " Loading @@ -6377,35 +6375,15 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR); return false; } matchingCodecs.add(info->getCodecName()); owners.add(info->getOwnerName() == nullptr ? "default" : info->getOwnerName()); } else { CHECK(msg->findString("mime", &mime)); if (!msg->findInt32("encoder", &encoder)) { encoder = false; } MediaCodecList::findMatchingCodecs( mime.c_str(), encoder, // createEncoder 0, // flags &matchingCodecs, &owners); } AString owner = (info->getOwnerName() == nullptr) ? "default" : info->getOwnerName(); sp<CodecObserver> observer = new CodecObserver; sp<IOMX> omx; sp<IOMXNode> omxNode; status_t err = NAME_NOT_FOUND; for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); ++matchIndex) { componentName = matchingCodecs[matchIndex]; OMXClient client; if (client.connect(owners[matchIndex].c_str()) != OK) { if (client.connect(owner.c_str()) != OK) { mCodec->signalError(OMX_ErrorUndefined, NO_INIT); return false; } Loading @@ -6417,22 +6395,8 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { err = omx->allocateNode(componentName.c_str(), observer, &omxNode); androidSetThreadPriority(tid, prevPriority); if (err == OK) { break; } else { ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); } omxNode = NULL; } if (omxNode == NULL) { if (!mime.empty()) { ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", encoder ? "en" : "de", mime.c_str(), err); } else { if (err != OK) { ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); } mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); return false; Loading media/libstagefright/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ cc_library_shared { "C2OMXNode.cpp", "CCodec.cpp", "CCodecBufferChannel.cpp", "Codec2InfoBuilder.cpp", "CodecBase.cpp", "CallbackDataSource.cpp", "CallbackMediaSource.cpp", Loading media/libstagefright/CCodec.cpp +55 −18 Original line number Diff line number Diff line Loading @@ -313,6 +313,19 @@ void CCodec::initiateConfigureComponent(const sp<AMessage> &format) { } void CCodec::configure(const sp<AMessage> &msg) { std::shared_ptr<C2ComponentInterface> intf; { Mutexed<State>::Locked state(mState); if (state->get() != ALLOCATED) { state->set(RELEASED); state.unlock(); mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); state.lock(); return; } intf = state->comp->intf(); } sp<AMessage> inputFormat(new AMessage); sp<AMessage> outputFormat(new AMessage); if (status_t err = [=] { Loading @@ -332,11 +345,34 @@ void CCodec::configure(const sp<AMessage> &msg) { setSurface(surface); } std::vector<std::unique_ptr<C2Param>> params; std::initializer_list<C2Param::Index> indices { C2PortMimeConfig::input::PARAM_TYPE, C2PortMimeConfig::output::PARAM_TYPE, }; c2_status_t c2err = intf->query_vb( {}, indices, C2_DONT_BLOCK, ¶ms); if (c2err != C2_OK) { ALOGE("Failed to query component interface: %d", c2err); return UNKNOWN_ERROR; } if (params.size() != indices.size()) { ALOGE("Component returns wrong number of params"); return UNKNOWN_ERROR; } if (!params[0] || !params[1]) { ALOGE("Component returns null params"); return UNKNOWN_ERROR; } inputFormat->setString("mime", ((C2PortMimeConfig *)params[0].get())->m.value); outputFormat->setString("mime", ((C2PortMimeConfig *)params[1].get())->m.value); // XXX: hack bool audio = mime.startsWithIgnoreCase("audio/"); if (encoder) { outputFormat->setString("mime", mime); inputFormat->setString("mime", AStringPrintf("%s/raw", audio ? "audio" : "video")); if (audio) { inputFormat->setInt32("channel-count", 1); inputFormat->setInt32("sample-rate", 44100); Loading @@ -347,8 +383,6 @@ void CCodec::configure(const sp<AMessage> &msg) { outputFormat->setInt32("height", 1920); } } else { inputFormat->setString("mime", mime); outputFormat->setString("mime", AStringPrintf("%s/raw", audio ? "audio" : "video")); if (audio) { outputFormat->setInt32("channel-count", 2); outputFormat->setInt32("sample-rate", 44100); Loading Loading @@ -712,7 +746,7 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatAllocate: { // C2ComponentStore::createComponent() should return within 100ms. setDeadline(now + 150ms); setDeadline(now + 150ms, "allocate"); AString componentName; CHECK(msg->findString("componentName", &componentName)); allocate(componentName); Loading @@ -720,7 +754,7 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { } case kWhatConfigure: { // C2Component::commit_sm() should return within 5ms. setDeadline(now + 50ms); setDeadline(now + 50ms, "configure"); sp<AMessage> format; CHECK(msg->findMessage("format", &format)); configure(format); Loading @@ -728,31 +762,31 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { } case kWhatStart: { // C2Component::start() should return within 500ms. setDeadline(now + 550ms); setDeadline(now + 550ms, "start"); start(); break; } case kWhatStop: { // C2Component::stop() should return within 500ms. setDeadline(now + 550ms); setDeadline(now + 550ms, "stop"); stop(); break; } case kWhatFlush: { // C2Component::flush_sm() should return within 5ms. setDeadline(now + 50ms); setDeadline(now + 50ms, "flush"); flush(); break; } case kWhatCreateInputSurface: { // Surface operations may be briefly blocking. setDeadline(now + 100ms); setDeadline(now + 100ms, "createInputSurface"); createInputSurface(); break; } case kWhatSetInputSurface: { // Surface operations may be briefly blocking. setDeadline(now + 100ms); setDeadline(now + 100ms, "setInputSurface"); sp<RefBase> obj; CHECK(msg->findObject("surface", &obj)); sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get())); Loading Loading @@ -780,25 +814,28 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { break; } } setDeadline(TimePoint::max()); setDeadline(TimePoint::max(), "none"); } void CCodec::setDeadline(const TimePoint &newDeadline) { Mutexed<TimePoint>::Locked deadline(mDeadline); *deadline = newDeadline; void CCodec::setDeadline(const TimePoint &newDeadline, const char *name) { Mutexed<NamedTimePoint>::Locked deadline(mDeadline); deadline->set(newDeadline, name); } void CCodec::initiateReleaseIfStuck() { std::string name; { Mutexed<TimePoint>::Locked deadline(mDeadline); if (*deadline >= std::chrono::steady_clock::now()) { Mutexed<NamedTimePoint>::Locked deadline(mDeadline); if (deadline->get() >= std::chrono::steady_clock::now()) { // We're not stuck. return; } name = deadline->getName(); } ALOGW("previous call to %s exceeded timeout", name.c_str()); mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); initiateRelease(); initiateRelease(false); } } // namespace android Loading
media/libmedia/MediaCodecInfo.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -141,6 +141,10 @@ bool MediaCodecInfo::isEncoder() const { return mIsEncoder; } uint32_t MediaCodecInfo::rank() const { return mRank; } void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const { mimes->clear(); for (size_t ix = 0; ix < mCaps.size(); ix++) { Loading Loading @@ -170,10 +174,12 @@ sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) { AString name = AString::FromParcel(parcel); AString owner = AString::FromParcel(parcel); bool isEncoder = static_cast<bool>(parcel.readInt32()); uint32_t rank = parcel.readUint32(); sp<MediaCodecInfo> info = new MediaCodecInfo; info->mName = name; info->mOwner = owner; info->mIsEncoder = isEncoder; info->mRank = rank; size_t size = static_cast<size_t>(parcel.readInt32()); for (size_t i = 0; i < size; i++) { AString mime = AString::FromParcel(parcel); Loading @@ -191,6 +197,7 @@ status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const { mName.writeToParcel(parcel); mOwner.writeToParcel(parcel); parcel->writeInt32(mIsEncoder); parcel->writeUint32(mRank); parcel->writeInt32(mCaps.size()); for (size_t i = 0; i < mCaps.size(); i++) { mCaps.keyAt(i).writeToParcel(parcel); Loading @@ -210,7 +217,7 @@ ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const { return -1; } MediaCodecInfo::MediaCodecInfo() { MediaCodecInfo::MediaCodecInfo() : mRank(0x100) { } void MediaCodecInfoWriter::setName(const char* name) { Loading @@ -225,6 +232,10 @@ void MediaCodecInfoWriter::setEncoder(bool isEncoder) { mInfo->mIsEncoder = isEncoder; } void MediaCodecInfoWriter::setRank(uint32_t rank) { mInfo->mRank = rank; } std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> MediaCodecInfoWriter::addMime(const char *mime) { ssize_t ix = mInfo->getCapabilityIndex(mime); Loading
media/libmedia/include/media/MediaCodecInfo.h +9 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,7 @@ struct MediaCodecInfo : public RefBase { * Currently, this is the "instance name" of the IOmx service. */ const char *getOwnerName() const; uint32_t rank() const; /** * Serialization over Binder Loading @@ -182,6 +183,7 @@ private: AString mOwner; bool mIsEncoder; KeyedVector<AString, sp<Capabilities> > mCaps; uint32_t mRank; ssize_t getCapabilityIndex(const char *mime) const; Loading Loading @@ -252,6 +254,13 @@ struct MediaCodecInfoWriter { * @return `true` if `mime` is removed; `false` if `mime` is not found. */ bool removeMime(const char* mime); /** * Set rank of the codec. MediaCodecList will stable-sort the list according * to rank in non-descending order. * * @param rank The rank of the component. */ void setRank(uint32_t rank); private: /** * The associated `MediaCodecInfo`. Loading
media/libstagefright/ACodec.cpp +38 −74 Original line number Diff line number Diff line Loading @@ -6349,11 +6349,9 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { Vector<AString> matchingCodecs; Vector<AString> owners; AString mime; AString componentName; int32_t encoder = false; if (msg->findString("componentName", &componentName)) { CHECK(msg->findString("componentName", &componentName)); sp<IMediaCodecList> list = MediaCodecList::getInstance(); if (list == nullptr) { ALOGE("Unable to obtain MediaCodecList while " Loading @@ -6377,35 +6375,15 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { mCodec->signalError(OMX_ErrorUndefined, UNKNOWN_ERROR); return false; } matchingCodecs.add(info->getCodecName()); owners.add(info->getOwnerName() == nullptr ? "default" : info->getOwnerName()); } else { CHECK(msg->findString("mime", &mime)); if (!msg->findInt32("encoder", &encoder)) { encoder = false; } MediaCodecList::findMatchingCodecs( mime.c_str(), encoder, // createEncoder 0, // flags &matchingCodecs, &owners); } AString owner = (info->getOwnerName() == nullptr) ? "default" : info->getOwnerName(); sp<CodecObserver> observer = new CodecObserver; sp<IOMX> omx; sp<IOMXNode> omxNode; status_t err = NAME_NOT_FOUND; for (size_t matchIndex = 0; matchIndex < matchingCodecs.size(); ++matchIndex) { componentName = matchingCodecs[matchIndex]; OMXClient client; if (client.connect(owners[matchIndex].c_str()) != OK) { if (client.connect(owner.c_str()) != OK) { mCodec->signalError(OMX_ErrorUndefined, NO_INIT); return false; } Loading @@ -6417,22 +6395,8 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) { err = omx->allocateNode(componentName.c_str(), observer, &omxNode); androidSetThreadPriority(tid, prevPriority); if (err == OK) { break; } else { ALOGW("Allocating component '%s' failed, try next one.", componentName.c_str()); } omxNode = NULL; } if (omxNode == NULL) { if (!mime.empty()) { ALOGE("Unable to instantiate a %scoder for type '%s' with err %#x.", encoder ? "en" : "de", mime.c_str(), err); } else { if (err != OK) { ALOGE("Unable to instantiate codec '%s' with err %#x.", componentName.c_str(), err); } mCodec->signalError((OMX_ERRORTYPE)err, makeNoSideEffectStatus(err)); return false; Loading
media/libstagefright/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ cc_library_shared { "C2OMXNode.cpp", "CCodec.cpp", "CCodecBufferChannel.cpp", "Codec2InfoBuilder.cpp", "CodecBase.cpp", "CallbackDataSource.cpp", "CallbackMediaSource.cpp", Loading
media/libstagefright/CCodec.cpp +55 −18 Original line number Diff line number Diff line Loading @@ -313,6 +313,19 @@ void CCodec::initiateConfigureComponent(const sp<AMessage> &format) { } void CCodec::configure(const sp<AMessage> &msg) { std::shared_ptr<C2ComponentInterface> intf; { Mutexed<State>::Locked state(mState); if (state->get() != ALLOCATED) { state->set(RELEASED); state.unlock(); mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); state.lock(); return; } intf = state->comp->intf(); } sp<AMessage> inputFormat(new AMessage); sp<AMessage> outputFormat(new AMessage); if (status_t err = [=] { Loading @@ -332,11 +345,34 @@ void CCodec::configure(const sp<AMessage> &msg) { setSurface(surface); } std::vector<std::unique_ptr<C2Param>> params; std::initializer_list<C2Param::Index> indices { C2PortMimeConfig::input::PARAM_TYPE, C2PortMimeConfig::output::PARAM_TYPE, }; c2_status_t c2err = intf->query_vb( {}, indices, C2_DONT_BLOCK, ¶ms); if (c2err != C2_OK) { ALOGE("Failed to query component interface: %d", c2err); return UNKNOWN_ERROR; } if (params.size() != indices.size()) { ALOGE("Component returns wrong number of params"); return UNKNOWN_ERROR; } if (!params[0] || !params[1]) { ALOGE("Component returns null params"); return UNKNOWN_ERROR; } inputFormat->setString("mime", ((C2PortMimeConfig *)params[0].get())->m.value); outputFormat->setString("mime", ((C2PortMimeConfig *)params[1].get())->m.value); // XXX: hack bool audio = mime.startsWithIgnoreCase("audio/"); if (encoder) { outputFormat->setString("mime", mime); inputFormat->setString("mime", AStringPrintf("%s/raw", audio ? "audio" : "video")); if (audio) { inputFormat->setInt32("channel-count", 1); inputFormat->setInt32("sample-rate", 44100); Loading @@ -347,8 +383,6 @@ void CCodec::configure(const sp<AMessage> &msg) { outputFormat->setInt32("height", 1920); } } else { inputFormat->setString("mime", mime); outputFormat->setString("mime", AStringPrintf("%s/raw", audio ? "audio" : "video")); if (audio) { outputFormat->setInt32("channel-count", 2); outputFormat->setInt32("sample-rate", 44100); Loading Loading @@ -712,7 +746,7 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { switch (msg->what()) { case kWhatAllocate: { // C2ComponentStore::createComponent() should return within 100ms. setDeadline(now + 150ms); setDeadline(now + 150ms, "allocate"); AString componentName; CHECK(msg->findString("componentName", &componentName)); allocate(componentName); Loading @@ -720,7 +754,7 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { } case kWhatConfigure: { // C2Component::commit_sm() should return within 5ms. setDeadline(now + 50ms); setDeadline(now + 50ms, "configure"); sp<AMessage> format; CHECK(msg->findMessage("format", &format)); configure(format); Loading @@ -728,31 +762,31 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { } case kWhatStart: { // C2Component::start() should return within 500ms. setDeadline(now + 550ms); setDeadline(now + 550ms, "start"); start(); break; } case kWhatStop: { // C2Component::stop() should return within 500ms. setDeadline(now + 550ms); setDeadline(now + 550ms, "stop"); stop(); break; } case kWhatFlush: { // C2Component::flush_sm() should return within 5ms. setDeadline(now + 50ms); setDeadline(now + 50ms, "flush"); flush(); break; } case kWhatCreateInputSurface: { // Surface operations may be briefly blocking. setDeadline(now + 100ms); setDeadline(now + 100ms, "createInputSurface"); createInputSurface(); break; } case kWhatSetInputSurface: { // Surface operations may be briefly blocking. setDeadline(now + 100ms); setDeadline(now + 100ms, "setInputSurface"); sp<RefBase> obj; CHECK(msg->findObject("surface", &obj)); sp<PersistentSurface> surface(static_cast<PersistentSurface *>(obj.get())); Loading Loading @@ -780,25 +814,28 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { break; } } setDeadline(TimePoint::max()); setDeadline(TimePoint::max(), "none"); } void CCodec::setDeadline(const TimePoint &newDeadline) { Mutexed<TimePoint>::Locked deadline(mDeadline); *deadline = newDeadline; void CCodec::setDeadline(const TimePoint &newDeadline, const char *name) { Mutexed<NamedTimePoint>::Locked deadline(mDeadline); deadline->set(newDeadline, name); } void CCodec::initiateReleaseIfStuck() { std::string name; { Mutexed<TimePoint>::Locked deadline(mDeadline); if (*deadline >= std::chrono::steady_clock::now()) { Mutexed<NamedTimePoint>::Locked deadline(mDeadline); if (deadline->get() >= std::chrono::steady_clock::now()) { // We're not stuck. return; } name = deadline->getName(); } ALOGW("previous call to %s exceeded timeout", name.c_str()); mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); initiateRelease(); initiateRelease(false); } } // namespace android