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

Commit 2ca00462 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "stagefright: add test for MediaCodec::reclaim/release race" am: c1532745 am: 7685a7c3

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/1432901

Change-Id: Ib3eb6c43812f7797700136f97b2316c175a97058
parents 958c7169 7685a7c3
Loading
Loading
Loading
Loading
+49 −27
Original line number Diff line number Diff line
@@ -614,7 +614,10 @@ sp<PersistentSurface> MediaCodec::CreatePersistentInputSurface() {
    return new PersistentSurface(bufferProducer, bufferSource);
}

MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
MediaCodec::MediaCodec(
        const sp<ALooper> &looper, pid_t pid, uid_t uid,
        std::function<sp<CodecBase>(const AString &, const char *)> getCodecBase,
        std::function<status_t(const AString &, sp<MediaCodecInfo> *)> getCodecInfo)
    : mState(UNINITIALIZED),
      mReleasedByResourceManager(false),
      mLooper(looper),
@@ -639,7 +642,9 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
      mNumLowLatencyDisables(0),
      mIsLowLatencyModeOn(false),
      mIndexOfFirstFrameWhenLowLatencyOn(-1),
      mInputBufferCounter(0) {
      mInputBufferCounter(0),
      mGetCodecBase(getCodecBase),
      mGetCodecInfo(getCodecInfo) {
    if (uid == kNoUid) {
        mUid = AIBinder_getCallingUid();
    } else {
@@ -647,6 +652,33 @@ MediaCodec::MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid)
    }
    mResourceManagerProxy = new ResourceManagerServiceProxy(pid, mUid,
            ::ndk::SharedRefBase::make<ResourceManagerClient>(this));
    if (!mGetCodecBase) {
        mGetCodecBase = [](const AString &name, const char *owner) {
            return GetCodecBase(name, owner);
        };
    }
    if (!mGetCodecInfo) {
        mGetCodecInfo = [](const AString &name, sp<MediaCodecInfo> *info) -> status_t {
            *info = nullptr;
            const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
            if (!mcl) {
                return NO_INIT;  // if called from Java should raise IOException
            }
            AString tmp = name;
            if (tmp.endsWith(".secure")) {
                tmp.erase(tmp.size() - 7, 7);
            }
            for (const AString &codecName : { name, tmp }) {
                ssize_t codecIdx = mcl->findCodecByName(codecName.c_str());
                if (codecIdx < 0) {
                    continue;
                }
                *info = mcl->getCodecInfo(codecIdx);
                return OK;
            }
            return NAME_NOT_FOUND;
        };
    }

    initMediametrics();
}
@@ -1090,40 +1122,30 @@ status_t MediaCodec::init(const AString &name) {
    bool secureCodec = false;
    const char *owner = "";
    if (!name.startsWith("android.filter.")) {
        AString tmp = name;
        if (tmp.endsWith(".secure")) {
            secureCodec = true;
            tmp.erase(tmp.size() - 7, 7);
        }
        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
        if (mcl == NULL) {
        status_t err = mGetCodecInfo(name, &mCodecInfo);
        if (err != OK) {
            mCodec = NULL;  // remove the codec.
            return NO_INIT; // if called from Java should raise IOException
            return err;
        }
        for (const AString &codecName : { name, tmp }) {
            ssize_t codecIdx = mcl->findCodecByName(codecName.c_str());
            if (codecIdx < 0) {
                continue;
        if (mCodecInfo == nullptr) {
            ALOGE("Getting codec info with name '%s' failed", name.c_str());
            return NAME_NOT_FOUND;
        }
            mCodecInfo = mcl->getCodecInfo(codecIdx);
        secureCodec = name.endsWith(".secure");
        Vector<AString> mediaTypes;
        mCodecInfo->getSupportedMediaTypes(&mediaTypes);
            for (size_t i = 0; i < mediaTypes.size(); i++) {
        for (size_t i = 0; i < mediaTypes.size(); ++i) {
            if (mediaTypes[i].startsWith("video/")) {
                mIsVideo = true;
                break;
            }
        }
            break;
        }
        if (mCodecInfo == nullptr) {
            return NAME_NOT_FOUND;
        }
        owner = mCodecInfo->getOwnerName();
    }

    mCodec = GetCodecBase(name, owner);
    mCodec = mGetCodecBase(name, owner);
    if (mCodec == NULL) {
        ALOGE("Getting codec base with name '%s' (owner='%s') failed", name.c_str(), owner);
        return NAME_NOT_FOUND;
    }

+3 −0
Original line number Diff line number Diff line
@@ -17,6 +17,9 @@
          "exclude-filter": "android.media.cts.AudioRecordTest"
        }
      ]
    },
    {
      "name": "mediacodecTest"
    }
  ],
  "postsubmit": [
+8 −1
Original line number Diff line number Diff line
@@ -429,7 +429,10 @@ private:

    std::shared_ptr<BufferChannelBase> mBufferChannel;

    MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid);
    MediaCodec(
            const sp<ALooper> &looper, pid_t pid, uid_t uid,
            std::function<sp<CodecBase>(const AString &, const char *)> getCodecBase = nullptr,
            std::function<status_t(const AString &, sp<MediaCodecInfo> *)> getCodecInfo = nullptr);

    static sp<CodecBase> GetCodecBase(const AString &name, const char *owner = nullptr);

@@ -574,6 +577,10 @@ private:

    Histogram mLatencyHist;

    std::function<sp<CodecBase>(const AString &, const char *)> mGetCodecBase;
    std::function<status_t(const AString &, sp<MediaCodecInfo> *)> mGetCodecInfo;
    friend class MediaTestHelper;

    DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};

+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#define MEDIA_CODEC_LIST_WRITER_H_

#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/MediaCodecListWriter.h>
#include <media/MediaCodecInfo.h>

#include <utils/Errors.h>
@@ -65,6 +64,7 @@ private:
    std::vector<sp<MediaCodecInfo>> mCodecInfos;

    friend struct MediaCodecList;
    friend class MediaTestHelper;
};

/**
+57 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

cc_test {
    name: "mediacodecTest",
    gtest: true,

    srcs: [
        "MediaCodecTest.cpp",
        "MediaTestHelper.cpp",
    ],

    shared_libs: [
        "libmedia",
        "libmedia_codeclist",
        "libmediametrics",
        "libmediandk",
        "libstagefright",
        "libstagefright_codecbase",
        "libstagefright_foundation",
        "libutils",
    ],

    static_libs: [
        "libgmock",
    ],

    cflags: [
        "-Werror",
        "-Wall",
    ],

    sanitize: {
        cfi: true,
        misc_undefined: [
            "unsigned-integer-overflow",
            "signed-integer-overflow",
        ],
    },

    test_suites: [
        "general-tests",
    ],
}
Loading