diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2020-03-20 23:13:19 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2020-03-20 23:13:19 +0000 |
commit | 66524524821c336e38c57a95ba9b360bdcc8f5d2 (patch) | |
tree | 5d6cc4114981ff98457f049397c0ef34a414a31f | |
parent | c674c9b8b445b8307791666aaba28dd049d29591 (diff) | |
parent | 40e794335b92f2f5237bcfddab454758cc4ad246 (diff) | |
download | frameworks_av-66524524821c336e38c57a95ba9b360bdcc8f5d2.tar.gz frameworks_av-66524524821c336e38c57a95ba9b360bdcc8f5d2.tar.bz2 frameworks_av-66524524821c336e38c57a95ba9b360bdcc8f5d2.zip |
Snap for 6317653 from 40e794335b92f2f5237bcfddab454758cc4ad246 to qt-qpr3-release
Change-Id: I6c96deb11617a96c07703eafa55edbc05f1c8746
-rw-r--r-- | media/codec2/sfplugin/CCodec.cpp | 21 | ||||
-rw-r--r-- | media/codec2/sfplugin/CCodec.h | 2 | ||||
-rw-r--r-- | media/codec2/sfplugin/CCodecBufferChannel.cpp | 38 | ||||
-rw-r--r-- | media/extractors/midi/Android.bp | 5 | ||||
-rw-r--r-- | media/extractors/midi/MidiExtractor.cpp | 12 | ||||
-rwxr-xr-x | media/extractors/mp4/MPEG4Extractor.cpp | 17 | ||||
-rw-r--r-- | media/libstagefright/foundation/OpusHeader.cpp | 4 | ||||
-rw-r--r-- | media/libwatchdog/Android.bp | 35 | ||||
-rw-r--r-- | media/libwatchdog/Watchdog.cpp | 63 | ||||
-rw-r--r-- | media/libwatchdog/include/watchdog/Watchdog.h | 49 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-arm.policy | 3 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy | 3 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-x86.policy | 3 | ||||
-rw-r--r-- | services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy | 3 |
14 files changed, 225 insertions, 33 deletions
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp index 4a31953a80..78ddd6d569 100644 --- a/media/codec2/sfplugin/CCodec.cpp +++ b/media/codec2/sfplugin/CCodec.cpp @@ -1286,7 +1286,8 @@ void CCodec::start() { { Mutexed<Config>::Locked config(mConfig); inputFormat = config->mInputFormat; - outputFormat = config->mOutputFormat; + // start triggers format dup + outputFormat = config->mOutputFormat = config->mOutputFormat->dup(); if (config->mInputSurface) { err2 = config->mInputSurface->start(); } @@ -1295,6 +1296,8 @@ void CCodec::start() { mCallback->onError(err2, ACTION_CODE_FATAL); return; } + // We're not starting after flush. + (void)mSentConfigAfterResume.test_and_set(); err2 = mChannel->start(inputFormat, outputFormat); if (err2 != OK) { mCallback->onError(err2, ACTION_CODE_FATAL); @@ -1523,18 +1526,26 @@ void CCodec::flush() { } void CCodec::signalResume() { - auto setResuming = [this] { + std::shared_ptr<Codec2Client::Component> comp; + auto setResuming = [this, &comp] { Mutexed<State>::Locked state(mState); if (state->get() != FLUSHED) { return UNKNOWN_ERROR; } state->set(RESUMING); + comp = state->comp; return OK; }; if (tryAndReportOnError(setResuming) != OK) { return; } + mSentConfigAfterResume.clear(); + { + Mutexed<Config>::Locked config(mConfig); + config->queryConfiguration(comp); + } + (void)mChannel->start(nullptr, nullptr); { @@ -1730,7 +1741,7 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { // handle configuration changes in work done Mutexed<Config>::Locked config(mConfig); - bool changed = false; + bool changed = !mSentConfigAfterResume.test_and_set(); Config::Watcher<C2StreamInitDataInfo::output> initData = config->watch<C2StreamInitDataInfo::output>(); if (!work->worklets.empty() @@ -1762,7 +1773,9 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) { ++stream; } - changed = config->updateConfiguration(updates, config->mOutputDomain); + if (config->updateConfiguration(updates, config->mOutputDomain)) { + changed = true; + } // copy standard infos to graphic buffers if not already present (otherwise, we // may overwrite the actual intermediate value with a final value) diff --git a/media/codec2/sfplugin/CCodec.h b/media/codec2/sfplugin/CCodec.h index b0b3c4f175..a580d1d20c 100644 --- a/media/codec2/sfplugin/CCodec.h +++ b/media/codec2/sfplugin/CCodec.h @@ -17,6 +17,7 @@ #ifndef C_CODEC_H_ #define C_CODEC_H_ +#include <atomic> #include <chrono> #include <list> #include <memory> @@ -175,6 +176,7 @@ private: typedef CCodecConfig Config; Mutexed<Config> mConfig; Mutexed<std::list<std::unique_ptr<C2Work>>> mWorkDoneQueue; + std::atomic_flag mSentConfigAfterResume; friend class CCodecCallbackImpl; diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp index 2efb9871e4..4ee6c1cd4f 100644 --- a/media/codec2/sfplugin/CCodecBufferChannel.cpp +++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp @@ -1072,7 +1072,7 @@ status_t CCodecBufferChannel::start( } else { output->buffers.reset(new LinearOutputBuffers(mName)); } - output->buffers->setFormat(outputFormat->dup()); + output->buffers->setFormat(outputFormat); // Try to set output surface to created block pool if given. @@ -1276,6 +1276,24 @@ bool CCodecBufferChannel::handleWork( std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat, const C2StreamInitDataInfo::output *initData) { + if (outputFormat != nullptr) { + Mutexed<Output>::Locked output(mOutput); + ALOGD("[%s] onWorkDone: output format changed to %s", + mName, outputFormat->debugString().c_str()); + output->buffers->setFormat(outputFormat); + + AString mediaType; + if (outputFormat->findString(KEY_MIME, &mediaType) + && mediaType == MIMETYPE_AUDIO_RAW) { + int32_t channelCount; + int32_t sampleRate; + if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount) + && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) { + output->buffers->updateSkipCutBuffer(sampleRate, channelCount); + } + } + } + if ((work->input.ordinal.frameIndex - mFirstValidFrameIndex.load()).peek() < 0) { // Discard frames from previous generation. ALOGD("[%s] Discard frames from previous generation.", mName); @@ -1453,24 +1471,6 @@ bool CCodecBufferChannel::handleWork( } } - if (outputFormat != nullptr) { - Mutexed<Output>::Locked output(mOutput); - ALOGD("[%s] onWorkDone: output format changed to %s", - mName, outputFormat->debugString().c_str()); - output->buffers->setFormat(outputFormat); - - AString mediaType; - if (outputFormat->findString(KEY_MIME, &mediaType) - && mediaType == MIMETYPE_AUDIO_RAW) { - int32_t channelCount; - int32_t sampleRate; - if (outputFormat->findInt32(KEY_CHANNEL_COUNT, &channelCount) - && outputFormat->findInt32(KEY_SAMPLE_RATE, &sampleRate)) { - output->buffers->updateSkipCutBuffer(sampleRate, channelCount); - } - } - } - int32_t flags = 0; if (worklet->output.flags & C2FrameData::FLAG_END_OF_STREAM) { flags |= MediaCodec::BUFFER_FLAG_EOS; diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp index 7d42e703f3..91ce78eb9d 100644 --- a/media/extractors/midi/Android.bp +++ b/media/extractors/midi/Android.bp @@ -14,7 +14,9 @@ cc_library_shared { static_libs: [ "libmedia_midiiowrapper", "libsonivox", - "libstagefright_foundation" + "libstagefright_foundation", + "libwatchdog", + "libbase", ], name: "libmidiextractor", relative_install_path: "extractors", @@ -35,5 +37,4 @@ cc_library_shared { "signed-integer-overflow", ], }, - } diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp index 9f4f9e69b4..d0efb2f652 100644 --- a/media/extractors/midi/MidiExtractor.cpp +++ b/media/extractors/midi/MidiExtractor.cpp @@ -26,6 +26,7 @@ #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaErrors.h> #include <libsonivox/eas_reverb.h> +#include <watchdog/Watchdog.h> namespace android { @@ -116,6 +117,7 @@ media_status_t MidiSource::read( MediaBufferHelper **outBuffer, const ReadOptions *options) { ALOGV("MidiSource::read"); + MediaBufferHelper *buffer; // process an optional seek request int64_t seekTimeUs; @@ -139,6 +141,8 @@ status_t MidiSource::init() } // MidiEngine +using namespace std::chrono_literals; +static constexpr auto kTimeout = 10s; MidiEngine::MidiEngine(CDataSource *dataSource, AMediaFormat *fileMetadata, @@ -147,6 +151,8 @@ MidiEngine::MidiEngine(CDataSource *dataSource, mEasHandle(NULL), mEasConfig(NULL), mIsInitialized(false) { + Watchdog watchdog(kTimeout); + mIoWrapper = new MidiIoWrapper(dataSource); // spin up a new EAS engine EAS_I32 temp; @@ -186,6 +192,8 @@ MidiEngine::MidiEngine(CDataSource *dataSource, } MidiEngine::~MidiEngine() { + Watchdog watchdog(kTimeout); + if (mEasHandle) { EAS_CloseFile(mEasData, mEasHandle); } @@ -217,12 +225,16 @@ status_t MidiEngine::releaseBuffers() { } status_t MidiEngine::seekTo(int64_t positionUs) { + Watchdog watchdog(kTimeout); + ALOGV("seekTo %lld", (long long)positionUs); EAS_RESULT result = EAS_Locate(mEasData, mEasHandle, positionUs / 1000, false); return result == EAS_SUCCESS ? OK : UNKNOWN_ERROR; } MediaBufferHelper* MidiEngine::readBuffer() { + Watchdog watchdog(kTimeout); + EAS_STATE state; EAS_State(mEasData, mEasHandle, &state); if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) { diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp index 9d5890c42c..14fe0dc444 100755 --- a/media/extractors/mp4/MPEG4Extractor.cpp +++ b/media/extractors/mp4/MPEG4Extractor.cpp @@ -5440,16 +5440,12 @@ status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { // apply some sanity (vs strict legality) checks // - // clamp the count of entries in the trun box, to avoid spending forever parsing - // this box. Clamping (vs error) lets us play *something*. - // 1 million is about 400 msecs on a Pixel3, should be no more than a couple seconds - // on the slowest devices. - static constexpr uint32_t kMaxTrunSampleCount = 1000000; + static constexpr uint32_t kMaxTrunSampleCount = 10000; if (sampleCount > kMaxTrunSampleCount) { - ALOGW("b/123389881 clamp sampleCount(%u) @ kMaxTrunSampleCount(%u)", + ALOGW("b/123389881 sampleCount(%u) > kMaxTrunSampleCount(%u)", sampleCount, kMaxTrunSampleCount); android_errorWriteLog(0x534e4554, "124389881 count"); - + return -EINVAL; } } @@ -5493,7 +5489,12 @@ status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) { tmp.duration = sampleDuration; tmp.compositionOffset = sampleCtsOffset; memset(tmp.iv, 0, sizeof(tmp.iv)); - mCurrentSamples.add(tmp); + if (mCurrentSamples.add(tmp) < 0) { + ALOGW("b/123389881 failed saving sample(n=%zu)", mCurrentSamples.size()); + android_errorWriteLog(0x534e4554, "124389881 allocation"); + mCurrentSamples.clear(); + return NO_MEMORY; + } dataOffset += sampleSize; } diff --git a/media/libstagefright/foundation/OpusHeader.cpp b/media/libstagefright/foundation/OpusHeader.cpp index 513e41f4a9..f5687e0d60 100644 --- a/media/libstagefright/foundation/OpusHeader.cpp +++ b/media/libstagefright/foundation/OpusHeader.cpp @@ -292,6 +292,10 @@ bool GetOpusHeaderBuffers(const uint8_t *data, size_t data_size, *opusHeadSize = data_size; return true; } else if (memcmp(AOPUS_CSD_MARKER_PREFIX, data, AOPUS_CSD_MARKER_PREFIX_SIZE) == 0) { + if (data_size < AOPUS_UNIFIED_CSD_MINSIZE || data_size > AOPUS_UNIFIED_CSD_MAXSIZE) { + ALOGD("Unexpected size for unified opus csd %zu", data_size); + return false; + } size_t i = 0; bool found = false; while (i <= data_size - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE) { diff --git a/media/libwatchdog/Android.bp b/media/libwatchdog/Android.bp new file mode 100644 index 0000000000..2bdf17262c --- /dev/null +++ b/media/libwatchdog/Android.bp @@ -0,0 +1,35 @@ +// Copyright 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_library { + name: "libwatchdog", + srcs: [ + "Watchdog.cpp", + ], + export_include_dirs: ["include"], + shared_libs: [ + "liblog", + ], + static_libs: [ + "libbase", + ], + target: { + windows: { + enabled: false, + }, + darwin: { + enabled: false, + }, + }, +} diff --git a/media/libwatchdog/Watchdog.cpp b/media/libwatchdog/Watchdog.cpp new file mode 100644 index 0000000000..bb012b9429 --- /dev/null +++ b/media/libwatchdog/Watchdog.cpp @@ -0,0 +1,63 @@ +/* + * 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. + */ + +#define LOG_TAG "Watchdog" + +#include <watchdog/Watchdog.h> + +#include <android-base/logging.h> +#include <android-base/threads.h> +#include <signal.h> +#include <time.h> +#include <cstring> +#include <utils/Log.h> + +namespace android { + +Watchdog::Watchdog(::std::chrono::steady_clock::duration timeout) { + // Create the timer. + struct sigevent sev; + sev.sigev_notify = SIGEV_THREAD_ID; + sev.sigev_notify_thread_id = base::GetThreadId(); + sev.sigev_signo = SIGABRT; + sev.sigev_value.sival_ptr = &mTimerId; + int err = timer_create(CLOCK_MONOTONIC, &sev, &mTimerId); + if (err != 0) { + PLOG(FATAL) << "Failed to create timer"; + } + + // Start the timer. + struct itimerspec spec; + memset(&spec, 0, sizeof(spec)); + auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(timeout); + LOG_ALWAYS_FATAL_IF(timeout.count() <= 0, "Duration must be positive"); + spec.it_value.tv_sec = ns.count() / 1000000000; + spec.it_value.tv_nsec = ns.count() % 1000000000; + err = timer_settime(mTimerId, 0, &spec, nullptr); + if (err != 0) { + PLOG(FATAL) << "Failed to start timer"; + } +} + +Watchdog::~Watchdog() { + // Delete the timer. + int err = timer_delete(mTimerId); + if (err != 0) { + PLOG(FATAL) << "Failed to delete timer"; + } +} + +} // namespace android diff --git a/media/libwatchdog/include/watchdog/Watchdog.h b/media/libwatchdog/include/watchdog/Watchdog.h new file mode 100644 index 0000000000..2819f8a270 --- /dev/null +++ b/media/libwatchdog/include/watchdog/Watchdog.h @@ -0,0 +1,49 @@ +/* + * 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. + */ + +#ifndef ANDROID_WATCHDOG_H +#define ANDROID_WATCHDOG_H + +#include <chrono> +#include <time.h> + +namespace android { + +/* + * An RAII-style object, which would crash the process if a timeout expires + * before the object is destroyed. + * The calling thread would be sent a SIGABORT, which would typically result in + * a stack trace. + * + * Sample usage: + * { + * Watchdog watchdog(std::chrono::milliseconds(10)); + * DoSomething(); + * } + * // If we got here, the function completed in time. + */ +class Watchdog final { +public: + Watchdog(std::chrono::steady_clock::duration timeout); + ~Watchdog(); + +private: + timer_t mTimerId; +}; + +} // namespace android + +#endif // ANDROID_WATCHDOG_H diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy index 38f9be6c7a..118072ec65 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy @@ -41,6 +41,9 @@ getegid32: 1 getgroups32: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for dynamically loading extractors pread64: 1 diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy index 8fd8787419..481e29e253 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy @@ -30,6 +30,9 @@ rt_sigreturn: 1 getrlimit: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for FileSource readlinkat: 1 diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy index 05915d11d9..15fb24e5ea 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy @@ -39,6 +39,9 @@ getegid32: 1 getgroups32: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for dynamically loading extractors getdents64: 1 diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy index e6a55d0586..4f2646c9cd 100644 --- a/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy +++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86_64.policy @@ -34,6 +34,9 @@ sched_setscheduler: 1 getrlimit: 1 nanosleep: 1 getrandom: 1 +timer_create: 1 +timer_settime: 1 +timer_delete: 1 # for dynamically loading extractors getdents64: 1 |