Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 685d33e5 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

release-request-108343c4-ad88-44f9-aaa2-24d8b8a5c176-for-git_oc-mr1-release-43...

release-request-108343c4-ad88-44f9-aaa2-24d8b8a5c176-for-git_oc-mr1-release-4321077 snap-temp-L97000000100182150

Change-Id: I08bbca0e8b26947af20fba2d0ebaa8ab2735f8d0
parents e505c9e4 2999d359
Loading
Loading
Loading
Loading
+40 −12
Original line number Diff line number Diff line
@@ -63,6 +63,14 @@ static int64_t convertTimespecToUs(const struct timespec &tv)
    return tv.tv_sec * 1000000ll + tv.tv_nsec / 1000;
}

// TODO move to audio_utils.
static inline struct timespec convertNsToTimespec(int64_t ns) {
    struct timespec tv;
    tv.tv_sec = static_cast<time_t>(ns / NANOS_PER_SECOND);
    tv.tv_nsec = static_cast<long>(ns % NANOS_PER_SECOND);
    return tv;
}

// current monotonic time in microseconds.
static int64_t getNowUs()
{
@@ -539,7 +547,8 @@ status_t AudioTrack::set(
    mUpdatePeriod = 0;
    mPosition = 0;
    mReleased = 0;
    mStartUs = 0;
    mStartNs = 0;
    mStartFromZeroUs = 0;
    AudioSystem::acquireAudioSessionId(mSessionId, mClientPid);
    mSequence = 1;
    mObservedSequence = mSequence;
@@ -587,6 +596,7 @@ status_t AudioTrack::start()
            mStartEts.clear();
        }
    }
    mStartNs = systemTime(); // save this for timestamp adjustment after starting.
    if (previousState == STATE_STOPPED || previousState == STATE_FLUSHED) {
        // reset current position as seen by client to 0
        mPosition = 0;
@@ -615,7 +625,7 @@ status_t AudioTrack::start()
        // since the flush is asynchronous and stop may not fully drain.
        // We save the time when the track is started to later verify whether
        // the counters are realistic (i.e. start from zero after this time).
        mStartUs = getNowUs();
        mStartFromZeroUs = mStartNs / 1000;

        // force refresh of remaining frames by processAudioBuffer() as last
        // write before stop could be partial.
@@ -2571,8 +2581,7 @@ status_t AudioTrack::getTimestamp_l(AudioTimestamp& timestamp)
                    if (at < limit) {
                        ALOGV("timestamp pause lag:%lld adjusting from %lld to %lld",
                                (long long)lag, (long long)at, (long long)limit);
                        timestamp.mTime.tv_sec = limit / NANOS_PER_SECOND;
                        timestamp.mTime.tv_nsec = limit % NANOS_PER_SECOND; // compiler opt.
                        timestamp.mTime = convertNsToTimespec(limit);
                    }
                }
                mPreviousLocation = location;
@@ -2615,18 +2624,18 @@ status_t AudioTrack::getTimestamp_l(AudioTimestamp& timestamp)
        // the previous song under gapless playback.
        // However, we sometimes see zero timestamps, then a glitch of
        // the previous song's position, and then correct timestamps afterwards.
        if (mStartUs != 0 && mSampleRate != 0) {
        if (mStartFromZeroUs != 0 && mSampleRate != 0) {
            static const int kTimeJitterUs = 100000; // 100 ms
            static const int k1SecUs = 1000000;

            const int64_t timeNow = getNowUs();

            if (timeNow < mStartUs + k1SecUs) { // within first second of starting
            if (timeNow < mStartFromZeroUs + k1SecUs) { // within first second of starting
                const int64_t timestampTimeUs = convertTimespecToUs(timestamp.mTime);
                if (timestampTimeUs < mStartUs) {
                if (timestampTimeUs < mStartFromZeroUs) {
                    return WOULD_BLOCK;  // stale timestamp time, occurs before start.
                }
                const int64_t deltaTimeUs = timestampTimeUs - mStartUs;
                const int64_t deltaTimeUs = timestampTimeUs - mStartFromZeroUs;
                const int64_t deltaPositionByUs = (double)timestamp.mPosition * 1000000
                        / ((double)mSampleRate * mPlaybackRate.mSpeed);

@@ -2649,10 +2658,10 @@ status_t AudioTrack::getTimestamp_l(AudioTimestamp& timestamp)
                    return WOULD_BLOCK;
                }
                if (deltaPositionByUs != 0) {
                    mStartUs = 0; // don't check again, we got valid nonzero position.
                    mStartFromZeroUs = 0; // don't check again, we got valid nonzero position.
                }
            } else {
                mStartUs = 0; // don't check again, start time expired.
                mStartFromZeroUs = 0; // don't check again, start time expired.
            }
            mTimestampStartupGlitchReported = false;
        }
@@ -2690,14 +2699,33 @@ status_t AudioTrack::getTimestamp_l(AudioTimestamp& timestamp)
    // Prevent retrograde motion in timestamp.
    // This is sometimes caused by erratic reports of the available space in the ALSA drivers.
    if (status == NO_ERROR) {
        // previousTimestampValid is set to false when starting after a stop or flush.
        if (previousTimestampValid) {
            const int64_t previousTimeNanos =
                    audio_utils_ns_from_timespec(&mPreviousTimestamp.mTime);
            const int64_t currentTimeNanos = audio_utils_ns_from_timespec(&timestamp.mTime);
            int64_t currentTimeNanos = audio_utils_ns_from_timespec(&timestamp.mTime);

            // Fix stale time when checking timestamp right after start().
            //
            // For offload compatibility, use a default lag value here.
            // Any time discrepancy between this update and the pause timestamp is handled
            // by the retrograde check afterwards.
            const int64_t lagNs = int64_t(mAfLatency * 1000000LL);
            const int64_t limitNs = mStartNs - lagNs;
            if (currentTimeNanos < limitNs) {
                ALOGD("correcting timestamp time for pause, "
                        "currentTimeNanos: %lld < limitNs: %lld < mStartNs: %lld",
                        (long long)currentTimeNanos, (long long)limitNs, (long long)mStartNs);
                timestamp.mTime = convertNsToTimespec(limitNs);
                currentTimeNanos = limitNs;
            }

            // retrograde check
            if (currentTimeNanos < previousTimeNanos) {
                ALOGW("retrograde timestamp time corrected, %lld < %lld",
                        (long long)currentTimeNanos, (long long)previousTimeNanos);
                timestamp.mTime = mPreviousTimestamp.mTime;
                // currentTimeNanos not used below.
            }

            // Looking at signed delta will work even when the timestamps
@@ -2907,7 +2935,7 @@ bool AudioTrack::hasStarted()
    case STATE_STOPPED:
        if (isOffloadedOrDirect_l()) {
            // check if we have started in the past to return true.
            return mStartUs > 0;
            return mStartFromZeroUs > 0;
        }
        // A normal audio track may still be draining, so
        // check if stream has ended.  This covers fasttrack position
+3 −1
Original line number Diff line number Diff line
@@ -1085,8 +1085,10 @@ protected:
                                                    // reset by stop() but continues monotonically
                                                    // after new IAudioTrack to restore mPosition,
                                                    // and could be easily widened to uint64_t
    int64_t                 mStartUs;               // the start time after flush or stop.
    int64_t                 mStartFromZeroUs;       // the start time after flush or stop,
                                                    // when position should be 0.
                                                    // only used for offloaded and direct tracks.
    int64_t                 mStartNs;               // the time when start() is called.
    ExtendedTimestamp       mStartEts;              // Extended timestamp at start for normal
                                                    // AudioTracks.
    AudioTimestamp          mStartTs;               // Timestamp at start for offloaded or direct
+15 −1
Original line number Diff line number Diff line
@@ -27,7 +27,8 @@
namespace android {

enum {
    GET_OMX = IBinder::FIRST_CALL_TRANSACTION
    GET_OMX = IBinder::FIRST_CALL_TRANSACTION,
    GET_OMX_STORE
};

class BpMediaCodecService : public BpInterface<IMediaCodecService>
@@ -45,6 +46,13 @@ public:
        return interface_cast<IOMX>(reply.readStrongBinder());
    }

    virtual sp<IOMXStore> getOMXStore() {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaCodecService::getInterfaceDescriptor());
        remote()->transact(GET_OMX_STORE, data, &reply);
        return interface_cast<IOMXStore>(reply.readStrongBinder());
    }

};

IMPLEMENT_META_INTERFACE(MediaCodecService, "android.media.IMediaCodecService");
@@ -62,6 +70,12 @@ status_t BnMediaCodecService::onTransact(
            reply->writeStrongBinder(IInterface::asBinder(omx));
            return NO_ERROR;
        }
        case GET_OMX_STORE: {
            CHECK_INTERFACE(IMediaCodecService, data, reply);
            sp<IOMXStore> omxStore = getOMXStore();
            reply->writeStrongBinder(IInterface::asBinder(omxStore));
            return NO_ERROR;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+61 −99
Original line number Diff line number Diff line
@@ -101,40 +101,44 @@ status_t MediaCodecInfo::Capabilities::writeToParcel(Parcel *parcel) const {
    return OK;
}

void MediaCodecInfo::CapabilitiesBuilder::addProfileLevel(uint32_t profile, uint32_t level) {
void MediaCodecInfo::CapabilitiesWriter::addDetail(
        const char* key, const char* value) {
    mCap->mDetails->setString(key, value);
}

void MediaCodecInfo::CapabilitiesWriter::addDetail(
        const char* key, int32_t value) {
    mCap->mDetails->setInt32(key, value);
}

void MediaCodecInfo::CapabilitiesWriter::addProfileLevel(
        uint32_t profile, uint32_t level) {
    ProfileLevel profileLevel;
    profileLevel.mProfile = profile;
    profileLevel.mLevel = level;
    if (mProfileLevelsSorted.indexOf(profileLevel) < 0) {
        mProfileLevels.push_back(profileLevel);
        mProfileLevelsSorted.add(profileLevel);
    if (mCap->mProfileLevelsSorted.indexOf(profileLevel) < 0) {
        mCap->mProfileLevels.push_back(profileLevel);
        mCap->mProfileLevelsSorted.add(profileLevel);
    }
}

void MediaCodecInfo::CapabilitiesBuilder::addColorFormat(uint32_t format) {
    if (mColorFormatsSorted.indexOf(format) < 0) {
        mColorFormats.push(format);
        mColorFormatsSorted.add(format);
void MediaCodecInfo::CapabilitiesWriter::addColorFormat(uint32_t format) {
    if (mCap->mColorFormatsSorted.indexOf(format) < 0) {
        mCap->mColorFormats.push(format);
        mCap->mColorFormatsSorted.add(format);
    }
}

void MediaCodecInfo::CapabilitiesBuilder::addFlags(uint32_t flags) {
    mFlags |= flags;
void MediaCodecInfo::CapabilitiesWriter::addFlags(uint32_t flags) {
    mCap->mFlags |= flags;
}

bool MediaCodecInfo::isEncoder() const {
    return mIsEncoder;
MediaCodecInfo::CapabilitiesWriter::CapabilitiesWriter(
        MediaCodecInfo::Capabilities* cap) : mCap(cap) {
}

bool MediaCodecInfo::hasQuirk(const char *name) const {
    if (name) {
        for (size_t ix = 0; ix < mQuirks.size(); ix++) {
            if (mQuirks.itemAt(ix).equalsIgnoreCase(name)) {
                return true;
            }
        }
    }
    return false;
bool MediaCodecInfo::isEncoder() const {
    return mIsEncoder;
}

void MediaCodecInfo::getSupportedMimes(Vector<AString> *mimes) const {
@@ -157,19 +161,20 @@ const char *MediaCodecInfo::getCodecName() const {
    return mName.c_str();
}

const char *MediaCodecInfo::getOwnerName() const {
    return mOwner.c_str();
}

// static
sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {
    AString name = AString::FromParcel(parcel);
    AString owner = AString::FromParcel(parcel);
    bool isEncoder = static_cast<bool>(parcel.readInt32());
    sp<MediaCodecInfo> info = new MediaCodecInfo(name, isEncoder, NULL);
    sp<MediaCodecInfo> info = new MediaCodecInfo;
    info->mName = name;
    info->mOwner = owner;
    info->mIsEncoder = isEncoder;
    size_t size = static_cast<size_t>(parcel.readInt32());
    for (size_t i = 0; i < size; i++) {
        AString quirk = AString::FromParcel(parcel);
        if (info != NULL) {
            info->mQuirks.push_back(quirk);
        }
    }
    size = static_cast<size_t>(parcel.readInt32());
    for (size_t i = 0; i < size; i++) {
        AString mime = AString::FromParcel(parcel);
        sp<Capabilities> caps = Capabilities::FromParcel(parcel);
@@ -184,11 +189,8 @@ sp<MediaCodecInfo> MediaCodecInfo::FromParcel(const Parcel &parcel) {

status_t MediaCodecInfo::writeToParcel(Parcel *parcel) const {
    mName.writeToParcel(parcel);
    mOwner.writeToParcel(parcel);
    parcel->writeInt32(mIsEncoder);
    parcel->writeInt32(mQuirks.size());
    for (size_t i = 0; i < mQuirks.size(); i++) {
        mQuirks.itemAt(i).writeToParcel(parcel);
    }
    parcel->writeInt32(mCaps.size());
    for (size_t i = 0; i < mCaps.size(); i++) {
        mCaps.keyAt(i).writeToParcel(parcel);
@@ -208,86 +210,46 @@ ssize_t MediaCodecInfo::getCapabilityIndex(const char *mime) const {
    return -1;
}

MediaCodecInfo::MediaCodecInfo(AString name, bool encoder, const char *mime)
    : mName(name),
      mIsEncoder(encoder),
      mHasSoleMime(false) {
    if (mime != NULL) {
        addMime(mime);
        mHasSoleMime = true;
    }
MediaCodecInfo::MediaCodecInfo() {
}

status_t MediaCodecInfo::addMime(const char *mime) {
    if (mHasSoleMime) {
        ALOGE("Codec '%s' already had its type specified", mName.c_str());
        return -EINVAL;
    }
    ssize_t ix = getCapabilityIndex(mime);
    if (ix >= 0) {
        mCurrentCaps = mCaps.valueAt(ix);
    } else {
        mCurrentCaps = new Capabilities();
        mCaps.add(AString(mime), mCurrentCaps);
    }
    return OK;
void MediaCodecInfoWriter::setName(const char* name) {
    mInfo->mName = name;
}

status_t MediaCodecInfo::updateMime(const char *mime) {
    ssize_t ix = getCapabilityIndex(mime);
    if (ix < 0) {
        ALOGE("updateMime mime not found %s", mime);
        return -EINVAL;
void MediaCodecInfoWriter::setOwner(const char* owner) {
    mInfo->mOwner = owner;
}

    mCurrentCaps = mCaps.valueAt(ix);
    return OK;
void MediaCodecInfoWriter::setEncoder(bool isEncoder) {
    mInfo->mIsEncoder = isEncoder;
}

void MediaCodecInfo::removeMime(const char *mime) {
    ssize_t ix = getCapabilityIndex(mime);
std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>
        MediaCodecInfoWriter::addMime(const char *mime) {
    ssize_t ix = mInfo->getCapabilityIndex(mime);
    if (ix >= 0) {
        mCaps.removeItemsAt(ix);
        // mCurrentCaps will be removed when completed
        return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
                new MediaCodecInfo::CapabilitiesWriter(
                mInfo->mCaps.valueAt(ix).get()));
    }
    sp<MediaCodecInfo::Capabilities> caps = new MediaCodecInfo::Capabilities();
    mInfo->mCaps.add(AString(mime), caps);
    return std::unique_ptr<MediaCodecInfo::CapabilitiesWriter>(
            new MediaCodecInfo::CapabilitiesWriter(caps.get()));
}

status_t MediaCodecInfo::initializeCapabilities(const sp<Capabilities> &caps) {
    // TRICKY: copy data to mCurrentCaps as it is a reference to
    // an element of the capabilites map.
    mCurrentCaps->mColorFormats.clear();
    mCurrentCaps->mColorFormats.appendVector(caps->mColorFormats);
    mCurrentCaps->mProfileLevels.clear();
    mCurrentCaps->mProfileLevels.appendVector(caps->mProfileLevels);
    mCurrentCaps->mFlags = caps->mFlags;
    mCurrentCaps->mDetails = caps->mDetails;
    return OK;
}

void MediaCodecInfo::addQuirk(const char *name) {
    if (!hasQuirk(name)) {
        mQuirks.push(name);
    }
}

void MediaCodecInfo::complete() {
    mCurrentCaps = NULL;
}

void MediaCodecInfo::addDetail(const AString &key, const AString &value) {
    mCurrentCaps->mDetails->setString(key.c_str(), value.c_str());
bool MediaCodecInfoWriter::removeMime(const char *mime) {
    ssize_t ix = mInfo->getCapabilityIndex(mime);
    if (ix >= 0) {
        mInfo->mCaps.removeItemsAt(ix);
        return true;
    }

void MediaCodecInfo::addFeature(const AString &key, int32_t value) {
    AString tag = "feature-";
    tag.append(key);
    mCurrentCaps->mDetails->setInt32(tag.c_str(), value);
    return false;
}

void MediaCodecInfo::addFeature(const AString &key, const char *value) {
    AString tag = "feature-";
    tag.append(key);
    mCurrentCaps->mDetails->setString(tag.c_str(), value);
MediaCodecInfoWriter::MediaCodecInfoWriter(MediaCodecInfo* info) :
    mInfo(info) {
}

}  // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <binder/Parcel.h>
#include <media/IDataSource.h>
#include <media/IOMX.h>
#include <media/IOMXStore.h>

namespace android {

@@ -31,6 +32,7 @@ public:
    DECLARE_META_INTERFACE(MediaCodecService);

    virtual sp<IOMX> getOMX() = 0;
    virtual sp<IOMXStore> getOMXStore() = 0;
};

class BnMediaCodecService: public BnInterface<IMediaCodecService>
Loading