Loading media/codec2/fuzzer/Android.bp +44 −21 Original line number Diff line number Diff line Loading @@ -38,7 +38,11 @@ cc_defaults { "-Wall", "-Werror", ], } cc_defaults { name: "C2Fuzzer-defaults-shipped", defaults: ["C2Fuzzer-defaults"], fuzz_config: { cc: [ "android-fwk-video@google.com", Loading @@ -55,9 +59,28 @@ cc_defaults { }, } cc_defaults { name: "C2Fuzzer-defaults-experimental", defaults: ["C2Fuzzer-defaults"], fuzz_config: { cc: [ "android-fwk-video@google.com", ], componentid: 1344, hotlists: [ "4593311", ], description: "The fuzzer targets the APIs of libcodec2", vector: "remote", service_privilege: "constrained", users: "multi_user", fuzzed_code_usage: "experimental", }, } cc_fuzz { name: "C2FuzzerAvcDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.avc.decoder\"", Loading @@ -71,7 +94,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerHevcDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.hevc.decoder\"", Loading @@ -85,7 +108,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerMpeg2Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.mpeg2.decoder\"", Loading @@ -99,7 +122,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerMpeg4Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.mpeg4.decoder\"", Loading @@ -113,7 +136,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerH263Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.h263.decoder\"", Loading @@ -127,7 +150,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerVp8Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.vp8.decoder\"", Loading @@ -141,7 +164,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerVp9Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.vp9.decoder\"", Loading @@ -155,7 +178,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAV1Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.av1.decoder\"", Loading @@ -170,7 +193,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAacDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.aac.decoder\"", Loading @@ -184,7 +207,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAmrnbDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.amrnb.decoder\"", Loading @@ -200,7 +223,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAmrwbDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.amrwb.decoder\"", Loading @@ -216,7 +239,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerFlacDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.flac.decoder\"", Loading @@ -231,7 +254,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerG711AlawDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.g711.alaw.decoder\"", Loading @@ -245,7 +268,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerG711MlawDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.g711.mlaw.decoder\"", Loading @@ -259,7 +282,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerGsmDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.gsm.decoder\"", Loading @@ -273,7 +296,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerMp3Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.mp3.decoder\"", Loading @@ -287,7 +310,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerOpusDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.opus.decoder\"", Loading @@ -301,7 +324,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerRawDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.raw.decoder\"", Loading @@ -314,7 +337,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerVorbisDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.vorbis.decoder\"", Loading @@ -328,7 +351,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerXaacDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-experimental"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.xaac.decoder\"", Loading media/codec2/vndk/C2Fence.cpp +62 −59 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <android-base/unique_fd.h> #include <cutils/native_handle.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <ui/Fence.h> #include <C2FenceFactory.h> Loading Loading @@ -631,26 +632,39 @@ C2Fence _C2FenceFactory::CreateMultiSyncFence( */ class _C2FenceFactory::PipeFenceImpl: public C2Fence::Impl { private: bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp, bool *event) const { // Wait for an event using ::ppoll() and handle any interruptions by signals // (EINTR) by retrying and accounting for time already waited. // Note: while ppoll in theory supports blocking signals, Linux NPTL library does // not allow blocking 2 realtime signals (see man nptl), so we do need to handle // signal interruptions. bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp) const { if (!mValid) { *hangUp = true; return true; return false; } struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; int64_t waitTimeNs = kPipeFenceWaitLimitSecs * 1000000000LL; if (timeoutNs >= 0) { ts.tv_sec = int(timeoutNs / 1000000000); ts.tv_nsec = timeoutNs % 1000000000; waitTimeNs = timeoutNs; } else { ALOGD("polling for indefinite duration requested, but changed to wait for %d sec", kPipeFenceWaitLimitSecs); ts.tv_sec = kPipeFenceWaitLimitSecs; ts.tv_nsec = 0; } int64_t startTsNs = android::elapsedRealtimeNano(); int64_t elapsedTsNs = 0; int tryNum = 0; int noEvent = 0; do { struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; ts.tv_sec = int((waitTimeNs - elapsedTsNs) / 1000000000); ts.tv_nsec = (waitTimeNs - elapsedTsNs) % 1000000000; ++tryNum; int ret = ::ppoll(&pfd, 1, &ts, nullptr); if (ret >= 0) { if (pfd.revents) { Loading @@ -659,22 +673,25 @@ private: *hangUp = true; mValid = false; ALOGD("PipeFenceImpl: pipe fd hangup or err event returned"); return false; } *event = true; return true; } // event not ready yet. return true; } if (errno == EINTR) { // poll() was cancelled by signal or inner kernel status. return false; } // Since poll error happened here, treat the error is irrecoverable. ++noEvent; // retry if the deadline does not meet yet. } else if (errno != EINTR) { ALOGE("PipeFenceImpl: poll() error %d", errno); *hangUp = true; mValid = false; return true; return false; } elapsedTsNs = android::elapsedRealtimeNano() - startTsNs; } while (elapsedTsNs < waitTimeNs); // EINTR till the end. // treat this as event not ready yet. ALOGV("PipeFenceImpl: tried %d times NoEvent %d times, spent %lld nanosecs", tryNum, noEvent, (long long)elapsedTsNs); return false; } public: Loading @@ -683,8 +700,7 @@ public: return C2_BAD_STATE; } bool hangUp = false; bool event = false; if (waitEvent(timeoutNs, &hangUp, &event)) { bool event = waitEvent(timeoutNs, &hangUp); if (hangUp) { return C2_BAD_STATE; } Loading @@ -692,9 +708,6 @@ public: return C2_OK; } return C2_TIMED_OUT; } else { return C2_CANCELED; } } virtual bool valid() const { Loading @@ -702,13 +715,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (hangUp) { return false; } } return true; (void)waitEvent(0, &hangUp); return !hangUp; } virtual bool ready() const { Loading @@ -716,13 +724,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (event) { return true; } } return false; bool event = waitEvent(0, &hangUp); return event; } virtual int fd() const { Loading media/libmedia/CodecCapabilities.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -407,9 +407,11 @@ void CodecCapabilities::init(std::vector<ProfileLevel> profLevs, std::vector<uin mMaxSupportedInstances = maxConcurrentInstances > 0 ? maxConcurrentInstances : DEFAULT_MAX_SUPPORTED_INSTANCES; int32_t maxInstances = mMaxSupportedInstances; capabilitiesInfo->findInt32("max-concurrent-instances", &maxInstances); AString maxConcurrentInstancesStr; int32_t maxInstances = capabilitiesInfo->findString("max-concurrent-instances", &maxConcurrentInstancesStr) ? (int32_t)strtol(maxConcurrentInstancesStr.c_str(), NULL, 10) : mMaxSupportedInstances; mMaxSupportedInstances = Range(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances); Loading media/libmedia/VideoCapabilities.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -311,8 +311,14 @@ bool VideoCapabilities::PerformancePoint::covers( int32_t width, height; format->findInt32(KEY_WIDTH, &width); format->findInt32(KEY_HEIGHT, &height); double frameRate; format->findDouble(KEY_FRAME_RATE, &frameRate); // Frame rate can be int32 or float. MediaCodec accept both float and int32 values. // We convert to a double since that can represent both i32 and float without precision loss. int32_t i32FrameRate; float fltFrameRate; double frameRate = format->findInt32(KEY_FRAME_RATE, &i32FrameRate) ? (double)i32FrameRate : format->findFloat(KEY_FRAME_RATE, &fltFrameRate) ? (double)fltFrameRate : 0; PerformancePoint other = PerformancePoint( width, height, // safely convert ceil(double) to int through float cast and std::round Loading Loading @@ -410,9 +416,16 @@ bool VideoCapabilities::supportsFormat(const sp<AMessage> &format) const { ? std::make_optional<int32_t>(widthVal) : std::nullopt; std::optional<int32_t> height = format->findInt32(KEY_HEIGHT, &heightVal) ? std::make_optional<int32_t>(heightVal) : std::nullopt; double rateVal; std::optional<double> rate = format->findDouble(KEY_FRAME_RATE, &rateVal) ? std::make_optional<double>(rateVal) : std::nullopt; // Frame rate can be int32 or float. MediaCodec accept both float and int32 values. // We convert to a double since that can represent both i32 and float without precision loss. int32_t i32RateVal; float fltRateVal; std::optional<double> rate = format->findInt32(KEY_FRAME_RATE, &i32RateVal) ? std::make_optional<double>((double)i32RateVal) : format->findFloat(KEY_FRAME_RATE, &fltRateVal) ? std::make_optional<double>((double)fltRateVal) : std::nullopt; if (!supports(width, height, rate)) { return false; Loading Loading @@ -479,11 +492,10 @@ void VideoCapabilities::initWithPlatformLimits() { mBlockAspectRatioRange = POSITIVE_RATIONALS; mAspectRatioRange = POSITIVE_RATIONALS; // YUV 4:2:0 requires 2:2 alignment mWidthAlignment = 2; mHeightAlignment = 2; mBlockWidth = 2; mBlockHeight = 2; mWidthAlignment = 1; mHeightAlignment = 1; mBlockWidth = 1; mBlockHeight = 1; mSmallerDimensionUpperLimit = VideoSize::GetAllowedDimensionRange().upper(); } Loading media/libstagefright/MediaCodec.cpp +27 −3 Original line number Diff line number Diff line Loading @@ -418,6 +418,7 @@ struct MediaCodec::ResourceManagerServiceProxy : void addResource(const MediaResourceParcel &resource); void addResource(const std::vector<MediaResourceParcel>& resources); void removeResource(const MediaResourceParcel &resource); void removeResource(const std::vector<MediaResourceParcel>& resources); void removeClient(); void markClientForPendingRemoval(); bool reclaimResource(const std::vector<MediaResourceParcel> &resources); Loading Loading @@ -649,17 +650,24 @@ void MediaCodec::ResourceManagerServiceProxy::addResource( void MediaCodec::ResourceManagerServiceProxy::removeResource( const MediaResourceParcel &resource) { std::vector<MediaResourceParcel> resources; resources.push_back(resource); removeResource(resources); } void MediaCodec::ResourceManagerServiceProxy::removeResource( const std::vector<MediaResourceParcel>& resources) { std::scoped_lock lock{mLock}; std::shared_ptr<IResourceManagerService> service = getService_l(); if (service == nullptr) { ALOGW("Service isn't available"); return; } std::vector<MediaResourceParcel> resources; resources.push_back(resource); service->removeResource(getClientInfo(), resources); for (const MediaResourceParcel& resource : resources) { mMediaResourceParcel.erase(resource); } } void MediaCodec::ResourceManagerServiceProxy::removeClient() { std::scoped_lock lock{mLock}; Loading Loading @@ -4548,6 +4556,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { CHECK_EQ(mState, STARTING); // Add the codec resources upon start. std::vector<MediaResourceParcel> resources; if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) { resources.push_back( Loading Loading @@ -4862,6 +4871,21 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mVideoRenderQualityTracker.resetForDiscontinuity(); } // Remove the codec resources upon stop. std::vector<MediaResourceParcel> resources; if (android::media::codec::codec_availability() && android::media::codec::codec_availability_support()) { Mutexed<std::vector<InstanceResourceInfo>>::Locked resourcesLocked( mRequiredResourceInfo); std::vector<InstanceResourceInfo>& requiredResourceInfo = *resourcesLocked; for (const InstanceResourceInfo& resource : requiredResourceInfo) { resources.push_back(getMediaResourceParcel(resource)); } } if (!resources.empty()) { mResourceManagerProxy->removeResource(resources); } // Notify the RM that the codec has been stopped. ClientConfigParcel clientConfig; initClientConfigParcel(clientConfig); Loading Loading
media/codec2/fuzzer/Android.bp +44 −21 Original line number Diff line number Diff line Loading @@ -38,7 +38,11 @@ cc_defaults { "-Wall", "-Werror", ], } cc_defaults { name: "C2Fuzzer-defaults-shipped", defaults: ["C2Fuzzer-defaults"], fuzz_config: { cc: [ "android-fwk-video@google.com", Loading @@ -55,9 +59,28 @@ cc_defaults { }, } cc_defaults { name: "C2Fuzzer-defaults-experimental", defaults: ["C2Fuzzer-defaults"], fuzz_config: { cc: [ "android-fwk-video@google.com", ], componentid: 1344, hotlists: [ "4593311", ], description: "The fuzzer targets the APIs of libcodec2", vector: "remote", service_privilege: "constrained", users: "multi_user", fuzzed_code_usage: "experimental", }, } cc_fuzz { name: "C2FuzzerAvcDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.avc.decoder\"", Loading @@ -71,7 +94,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerHevcDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.hevc.decoder\"", Loading @@ -85,7 +108,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerMpeg2Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.mpeg2.decoder\"", Loading @@ -99,7 +122,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerMpeg4Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.mpeg4.decoder\"", Loading @@ -113,7 +136,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerH263Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.h263.decoder\"", Loading @@ -127,7 +150,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerVp8Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.vp8.decoder\"", Loading @@ -141,7 +164,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerVp9Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.vp9.decoder\"", Loading @@ -155,7 +178,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAV1Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.av1.decoder\"", Loading @@ -170,7 +193,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAacDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.aac.decoder\"", Loading @@ -184,7 +207,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAmrnbDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.amrnb.decoder\"", Loading @@ -200,7 +223,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerAmrwbDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.amrwb.decoder\"", Loading @@ -216,7 +239,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerFlacDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.flac.decoder\"", Loading @@ -231,7 +254,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerG711AlawDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.g711.alaw.decoder\"", Loading @@ -245,7 +268,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerG711MlawDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.g711.mlaw.decoder\"", Loading @@ -259,7 +282,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerGsmDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.gsm.decoder\"", Loading @@ -273,7 +296,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerMp3Dec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.mp3.decoder\"", Loading @@ -287,7 +310,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerOpusDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.opus.decoder\"", Loading @@ -301,7 +324,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerRawDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.raw.decoder\"", Loading @@ -314,7 +337,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerVorbisDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-shipped"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.vorbis.decoder\"", Loading @@ -328,7 +351,7 @@ cc_fuzz { cc_fuzz { name: "C2FuzzerXaacDec", defaults: ["C2Fuzzer-defaults"], defaults: ["C2Fuzzer-defaults-experimental"], cflags: [ "-DC2COMPONENTNAME=\"c2.android.xaac.decoder\"", Loading
media/codec2/vndk/C2Fence.cpp +62 −59 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <android-base/unique_fd.h> #include <cutils/native_handle.h> #include <utils/Log.h> #include <utils/SystemClock.h> #include <ui/Fence.h> #include <C2FenceFactory.h> Loading Loading @@ -631,26 +632,39 @@ C2Fence _C2FenceFactory::CreateMultiSyncFence( */ class _C2FenceFactory::PipeFenceImpl: public C2Fence::Impl { private: bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp, bool *event) const { // Wait for an event using ::ppoll() and handle any interruptions by signals // (EINTR) by retrying and accounting for time already waited. // Note: while ppoll in theory supports blocking signals, Linux NPTL library does // not allow blocking 2 realtime signals (see man nptl), so we do need to handle // signal interruptions. bool waitEvent(c2_nsecs_t timeoutNs, bool *hangUp) const { if (!mValid) { *hangUp = true; return true; return false; } struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; int64_t waitTimeNs = kPipeFenceWaitLimitSecs * 1000000000LL; if (timeoutNs >= 0) { ts.tv_sec = int(timeoutNs / 1000000000); ts.tv_nsec = timeoutNs % 1000000000; waitTimeNs = timeoutNs; } else { ALOGD("polling for indefinite duration requested, but changed to wait for %d sec", kPipeFenceWaitLimitSecs); ts.tv_sec = kPipeFenceWaitLimitSecs; ts.tv_nsec = 0; } int64_t startTsNs = android::elapsedRealtimeNano(); int64_t elapsedTsNs = 0; int tryNum = 0; int noEvent = 0; do { struct pollfd pfd; pfd.fd = mPipeFd.get(); pfd.events = POLLIN; pfd.revents = 0; struct timespec ts; ts.tv_sec = int((waitTimeNs - elapsedTsNs) / 1000000000); ts.tv_nsec = (waitTimeNs - elapsedTsNs) % 1000000000; ++tryNum; int ret = ::ppoll(&pfd, 1, &ts, nullptr); if (ret >= 0) { if (pfd.revents) { Loading @@ -659,22 +673,25 @@ private: *hangUp = true; mValid = false; ALOGD("PipeFenceImpl: pipe fd hangup or err event returned"); return false; } *event = true; return true; } // event not ready yet. return true; } if (errno == EINTR) { // poll() was cancelled by signal or inner kernel status. return false; } // Since poll error happened here, treat the error is irrecoverable. ++noEvent; // retry if the deadline does not meet yet. } else if (errno != EINTR) { ALOGE("PipeFenceImpl: poll() error %d", errno); *hangUp = true; mValid = false; return true; return false; } elapsedTsNs = android::elapsedRealtimeNano() - startTsNs; } while (elapsedTsNs < waitTimeNs); // EINTR till the end. // treat this as event not ready yet. ALOGV("PipeFenceImpl: tried %d times NoEvent %d times, spent %lld nanosecs", tryNum, noEvent, (long long)elapsedTsNs); return false; } public: Loading @@ -683,8 +700,7 @@ public: return C2_BAD_STATE; } bool hangUp = false; bool event = false; if (waitEvent(timeoutNs, &hangUp, &event)) { bool event = waitEvent(timeoutNs, &hangUp); if (hangUp) { return C2_BAD_STATE; } Loading @@ -692,9 +708,6 @@ public: return C2_OK; } return C2_TIMED_OUT; } else { return C2_CANCELED; } } virtual bool valid() const { Loading @@ -702,13 +715,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (hangUp) { return false; } } return true; (void)waitEvent(0, &hangUp); return !hangUp; } virtual bool ready() const { Loading @@ -716,13 +724,8 @@ public: return false; } bool hangUp = false; bool event = false; if (waitEvent(0, &hangUp, &event)) { if (event) { return true; } } return false; bool event = waitEvent(0, &hangUp); return event; } virtual int fd() const { Loading
media/libmedia/CodecCapabilities.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -407,9 +407,11 @@ void CodecCapabilities::init(std::vector<ProfileLevel> profLevs, std::vector<uin mMaxSupportedInstances = maxConcurrentInstances > 0 ? maxConcurrentInstances : DEFAULT_MAX_SUPPORTED_INSTANCES; int32_t maxInstances = mMaxSupportedInstances; capabilitiesInfo->findInt32("max-concurrent-instances", &maxInstances); AString maxConcurrentInstancesStr; int32_t maxInstances = capabilitiesInfo->findString("max-concurrent-instances", &maxConcurrentInstancesStr) ? (int32_t)strtol(maxConcurrentInstancesStr.c_str(), NULL, 10) : mMaxSupportedInstances; mMaxSupportedInstances = Range(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances); Loading
media/libmedia/VideoCapabilities.cpp +22 −10 Original line number Diff line number Diff line Loading @@ -311,8 +311,14 @@ bool VideoCapabilities::PerformancePoint::covers( int32_t width, height; format->findInt32(KEY_WIDTH, &width); format->findInt32(KEY_HEIGHT, &height); double frameRate; format->findDouble(KEY_FRAME_RATE, &frameRate); // Frame rate can be int32 or float. MediaCodec accept both float and int32 values. // We convert to a double since that can represent both i32 and float without precision loss. int32_t i32FrameRate; float fltFrameRate; double frameRate = format->findInt32(KEY_FRAME_RATE, &i32FrameRate) ? (double)i32FrameRate : format->findFloat(KEY_FRAME_RATE, &fltFrameRate) ? (double)fltFrameRate : 0; PerformancePoint other = PerformancePoint( width, height, // safely convert ceil(double) to int through float cast and std::round Loading Loading @@ -410,9 +416,16 @@ bool VideoCapabilities::supportsFormat(const sp<AMessage> &format) const { ? std::make_optional<int32_t>(widthVal) : std::nullopt; std::optional<int32_t> height = format->findInt32(KEY_HEIGHT, &heightVal) ? std::make_optional<int32_t>(heightVal) : std::nullopt; double rateVal; std::optional<double> rate = format->findDouble(KEY_FRAME_RATE, &rateVal) ? std::make_optional<double>(rateVal) : std::nullopt; // Frame rate can be int32 or float. MediaCodec accept both float and int32 values. // We convert to a double since that can represent both i32 and float without precision loss. int32_t i32RateVal; float fltRateVal; std::optional<double> rate = format->findInt32(KEY_FRAME_RATE, &i32RateVal) ? std::make_optional<double>((double)i32RateVal) : format->findFloat(KEY_FRAME_RATE, &fltRateVal) ? std::make_optional<double>((double)fltRateVal) : std::nullopt; if (!supports(width, height, rate)) { return false; Loading Loading @@ -479,11 +492,10 @@ void VideoCapabilities::initWithPlatformLimits() { mBlockAspectRatioRange = POSITIVE_RATIONALS; mAspectRatioRange = POSITIVE_RATIONALS; // YUV 4:2:0 requires 2:2 alignment mWidthAlignment = 2; mHeightAlignment = 2; mBlockWidth = 2; mBlockHeight = 2; mWidthAlignment = 1; mHeightAlignment = 1; mBlockWidth = 1; mBlockHeight = 1; mSmallerDimensionUpperLimit = VideoSize::GetAllowedDimensionRange().upper(); } Loading
media/libstagefright/MediaCodec.cpp +27 −3 Original line number Diff line number Diff line Loading @@ -418,6 +418,7 @@ struct MediaCodec::ResourceManagerServiceProxy : void addResource(const MediaResourceParcel &resource); void addResource(const std::vector<MediaResourceParcel>& resources); void removeResource(const MediaResourceParcel &resource); void removeResource(const std::vector<MediaResourceParcel>& resources); void removeClient(); void markClientForPendingRemoval(); bool reclaimResource(const std::vector<MediaResourceParcel> &resources); Loading Loading @@ -649,17 +650,24 @@ void MediaCodec::ResourceManagerServiceProxy::addResource( void MediaCodec::ResourceManagerServiceProxy::removeResource( const MediaResourceParcel &resource) { std::vector<MediaResourceParcel> resources; resources.push_back(resource); removeResource(resources); } void MediaCodec::ResourceManagerServiceProxy::removeResource( const std::vector<MediaResourceParcel>& resources) { std::scoped_lock lock{mLock}; std::shared_ptr<IResourceManagerService> service = getService_l(); if (service == nullptr) { ALOGW("Service isn't available"); return; } std::vector<MediaResourceParcel> resources; resources.push_back(resource); service->removeResource(getClientInfo(), resources); for (const MediaResourceParcel& resource : resources) { mMediaResourceParcel.erase(resource); } } void MediaCodec::ResourceManagerServiceProxy::removeClient() { std::scoped_lock lock{mLock}; Loading Loading @@ -4548,6 +4556,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { CHECK_EQ(mState, STARTING); // Add the codec resources upon start. std::vector<MediaResourceParcel> resources; if (mDomain == DOMAIN_VIDEO || mDomain == DOMAIN_IMAGE) { resources.push_back( Loading Loading @@ -4862,6 +4871,21 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { mVideoRenderQualityTracker.resetForDiscontinuity(); } // Remove the codec resources upon stop. std::vector<MediaResourceParcel> resources; if (android::media::codec::codec_availability() && android::media::codec::codec_availability_support()) { Mutexed<std::vector<InstanceResourceInfo>>::Locked resourcesLocked( mRequiredResourceInfo); std::vector<InstanceResourceInfo>& requiredResourceInfo = *resourcesLocked; for (const InstanceResourceInfo& resource : requiredResourceInfo) { resources.push_back(getMediaResourceParcel(resource)); } } if (!resources.empty()) { mResourceManagerProxy->removeResource(resources); } // Notify the RM that the codec has been stopped. ClientConfigParcel clientConfig; initClientConfigParcel(clientConfig); Loading