Loading drm/mediadrm/plugins/TEST_MAPPING +1 −10 Original line number Diff line number Diff line { "presubmit": [ { "name": "CtsMediaDrmTestCases", "name": "CtsMediaDrmFrameworkTestCases", "options" : [ { "include-annotation": "android.platform.test.annotations.Presubmit" }, { "include-filter": "android.mediadrm.cts.MediaDrmClearkeyTest" }, { "include-filter": "android.mediadrm.cts.MediaDrmMetricsTest" }, { "include-filter": "android.mediadrm.cts.NativeMediaDrmClearkeyTest" } ] } Loading media/libaaudio/src/legacy/AudioStreamRecord.cpp +2 −23 Original line number Diff line number Diff line Loading @@ -96,29 +96,8 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) setFormat(AUDIO_FORMAT_PCM_FLOAT); } // Maybe change device format to get a FAST path. // AudioRecord does not support FAST mode for FLOAT data. // TODO AudioRecord should allow FLOAT data paths for FAST tracks. // So IF the user asks for low latency FLOAT // AND the sampleRate is likely to be compatible with FAST // THEN request I16 and convert to FLOAT when passing to user. // Note that hard coding 48000 Hz is not ideal because the sampleRate // for a FAST path might not be 48000 Hz. // It normally is but there is a chance that it is not. // And there is no reliable way to know that in advance. // Luckily the consequences of a wrong guess are minor. // We just may not get a FAST track. // But we wouldn't have anyway without this hack. constexpr int32_t kMostLikelySampleRateForFast = 48000; if (getFormat() == AUDIO_FORMAT_PCM_FLOAT && perfMode == AAUDIO_PERFORMANCE_MODE_LOW_LATENCY && (audio_channel_count_from_in_mask(channelMask) <= 2) // FAST only for mono and stereo && (getSampleRate() == kMostLikelySampleRateForFast || getSampleRate() == AAUDIO_UNSPECIFIED)) { setDeviceFormat(AUDIO_FORMAT_PCM_16_BIT); } else { setDeviceFormat(getFormat()); } // To avoid glitching, let AudioFlinger pick the optimal burst size. uint32_t notificationFrames = 0; Loading media/libstagefright/MediaCodec.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -2151,7 +2151,7 @@ static void mapFormat(AString componentName, const sp<AMessage> &format, const c bool reverse) { AString mediaType; if (!format->findString("mime", &mediaType)) { ALOGW("mapFormat: no mediaType information"); ALOGV("mapFormat: no mediaType information"); return; } ALOGV("mapFormat: codec %s mediatype %s kind %s reverse %d", componentName.c_str(), Loading Loading @@ -3105,10 +3105,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case STOPPING: { if (mFlags & kFlagSawMediaServerDie) { bool postPendingReplies = true; if (mState == RELEASING && !mReplyID) { ALOGD("Releasing asynchronously, so nothing to reply here."); postPendingReplies = false; } // MediaServer died, there definitely won't // be a shutdown complete notification after Loading @@ -3121,8 +3119,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if (mState == RELEASING) { mComponentName.clear(); } if (postPendingReplies) { if (mReplyID) { postPendingRepliesAndDeferredMessages(origin + ":dead"); } else { ALOGD("no pending replies: %s:dead following %s", origin.c_str(), mLastReplyOrigin.c_str()); } sendErrorResponse = false; } else if (!mReplyID) { Loading media/libstagefright/tests/mediacodec/MediaCodecTest.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -393,3 +393,51 @@ TEST(MediaCodecTest, DeadWhileAsyncReleasing) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); looper->stop(); } TEST(MediaCodecTest, DeadWhileStoppingError) { // Test scenario: // // 1) Client thread calls stop(); MediaCodec looper thread calls // initiateShutdown(); shutdown is being handled at the component thread. // 2) An error occurs while handling initiateShutdown(). // 3) MediaCodec looper thread handles the error. // 4) Codec service dies after the error is handled // 5) MediaCodec looper thread handles the death. static const AString kCodecName{"test.codec"}; static const AString kCodecOwner{"nobody"}; static const AString kMediaType{"video/x-test"}; sp<MockCodec> mockCodec; std::function<sp<CodecBase>(const AString &name, const char *owner)> getCodecBase = [&mockCodec](const AString &, const char *) { mockCodec = new MockCodec([](const std::shared_ptr<MockBufferChannel> &) { // No mock setup, as we don't expect any buffer operations // in this scenario. }); ON_CALL(*mockCodec, initiateAllocateComponent(_)) .WillByDefault([mockCodec](const sp<AMessage> &) { mockCodec->callback()->onComponentAllocated(kCodecName.c_str()); }); ON_CALL(*mockCodec, initiateShutdown(_)) .WillByDefault([mockCodec](bool) { // 2) mockCodec->callback()->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); // 4) mockCodec->callback()->onError(DEAD_OBJECT, ACTION_CODE_FATAL); // Codec service has died, no callback. }); return mockCodec; }; sp<ALooper> looper{new ALooper}; sp<MediaCodec> codec = SetupMediaCodec( kCodecOwner, kCodecName, kMediaType, looper, getCodecBase); ASSERT_NE(nullptr, codec) << "Codec must not be null"; ASSERT_NE(nullptr, mockCodec) << "MockCodec must not be null"; codec->stop(); // sleep here so that the looper thread can handle the error std::this_thread::sleep_for(std::chrono::milliseconds(100)); looper->stop(); } services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +2 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,8 @@ public: uint32_t getRecommendedMuteDurationMs() const override; void setTracksInvalidatedStatusByStrategy(product_strategy_t strategy); const sp<IOProfile> mProfile; // I/O profile this output derives from audio_io_handle_t mIoHandle; // output handle uint32_t mLatency; // Loading Loading
drm/mediadrm/plugins/TEST_MAPPING +1 −10 Original line number Diff line number Diff line { "presubmit": [ { "name": "CtsMediaDrmTestCases", "name": "CtsMediaDrmFrameworkTestCases", "options" : [ { "include-annotation": "android.platform.test.annotations.Presubmit" }, { "include-filter": "android.mediadrm.cts.MediaDrmClearkeyTest" }, { "include-filter": "android.mediadrm.cts.MediaDrmMetricsTest" }, { "include-filter": "android.mediadrm.cts.NativeMediaDrmClearkeyTest" } ] } Loading
media/libaaudio/src/legacy/AudioStreamRecord.cpp +2 −23 Original line number Diff line number Diff line Loading @@ -96,29 +96,8 @@ aaudio_result_t AudioStreamRecord::open(const AudioStreamBuilder& builder) setFormat(AUDIO_FORMAT_PCM_FLOAT); } // Maybe change device format to get a FAST path. // AudioRecord does not support FAST mode for FLOAT data. // TODO AudioRecord should allow FLOAT data paths for FAST tracks. // So IF the user asks for low latency FLOAT // AND the sampleRate is likely to be compatible with FAST // THEN request I16 and convert to FLOAT when passing to user. // Note that hard coding 48000 Hz is not ideal because the sampleRate // for a FAST path might not be 48000 Hz. // It normally is but there is a chance that it is not. // And there is no reliable way to know that in advance. // Luckily the consequences of a wrong guess are minor. // We just may not get a FAST track. // But we wouldn't have anyway without this hack. constexpr int32_t kMostLikelySampleRateForFast = 48000; if (getFormat() == AUDIO_FORMAT_PCM_FLOAT && perfMode == AAUDIO_PERFORMANCE_MODE_LOW_LATENCY && (audio_channel_count_from_in_mask(channelMask) <= 2) // FAST only for mono and stereo && (getSampleRate() == kMostLikelySampleRateForFast || getSampleRate() == AAUDIO_UNSPECIFIED)) { setDeviceFormat(AUDIO_FORMAT_PCM_16_BIT); } else { setDeviceFormat(getFormat()); } // To avoid glitching, let AudioFlinger pick the optimal burst size. uint32_t notificationFrames = 0; Loading
media/libstagefright/MediaCodec.cpp +5 −4 Original line number Diff line number Diff line Loading @@ -2151,7 +2151,7 @@ static void mapFormat(AString componentName, const sp<AMessage> &format, const c bool reverse) { AString mediaType; if (!format->findString("mime", &mediaType)) { ALOGW("mapFormat: no mediaType information"); ALOGV("mapFormat: no mediaType information"); return; } ALOGV("mapFormat: codec %s mediatype %s kind %s reverse %d", componentName.c_str(), Loading Loading @@ -3105,10 +3105,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { case STOPPING: { if (mFlags & kFlagSawMediaServerDie) { bool postPendingReplies = true; if (mState == RELEASING && !mReplyID) { ALOGD("Releasing asynchronously, so nothing to reply here."); postPendingReplies = false; } // MediaServer died, there definitely won't // be a shutdown complete notification after Loading @@ -3121,8 +3119,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) { if (mState == RELEASING) { mComponentName.clear(); } if (postPendingReplies) { if (mReplyID) { postPendingRepliesAndDeferredMessages(origin + ":dead"); } else { ALOGD("no pending replies: %s:dead following %s", origin.c_str(), mLastReplyOrigin.c_str()); } sendErrorResponse = false; } else if (!mReplyID) { Loading
media/libstagefright/tests/mediacodec/MediaCodecTest.cpp +48 −0 Original line number Diff line number Diff line Loading @@ -393,3 +393,51 @@ TEST(MediaCodecTest, DeadWhileAsyncReleasing) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); looper->stop(); } TEST(MediaCodecTest, DeadWhileStoppingError) { // Test scenario: // // 1) Client thread calls stop(); MediaCodec looper thread calls // initiateShutdown(); shutdown is being handled at the component thread. // 2) An error occurs while handling initiateShutdown(). // 3) MediaCodec looper thread handles the error. // 4) Codec service dies after the error is handled // 5) MediaCodec looper thread handles the death. static const AString kCodecName{"test.codec"}; static const AString kCodecOwner{"nobody"}; static const AString kMediaType{"video/x-test"}; sp<MockCodec> mockCodec; std::function<sp<CodecBase>(const AString &name, const char *owner)> getCodecBase = [&mockCodec](const AString &, const char *) { mockCodec = new MockCodec([](const std::shared_ptr<MockBufferChannel> &) { // No mock setup, as we don't expect any buffer operations // in this scenario. }); ON_CALL(*mockCodec, initiateAllocateComponent(_)) .WillByDefault([mockCodec](const sp<AMessage> &) { mockCodec->callback()->onComponentAllocated(kCodecName.c_str()); }); ON_CALL(*mockCodec, initiateShutdown(_)) .WillByDefault([mockCodec](bool) { // 2) mockCodec->callback()->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL); // 4) mockCodec->callback()->onError(DEAD_OBJECT, ACTION_CODE_FATAL); // Codec service has died, no callback. }); return mockCodec; }; sp<ALooper> looper{new ALooper}; sp<MediaCodec> codec = SetupMediaCodec( kCodecOwner, kCodecName, kMediaType, looper, getCodecBase); ASSERT_NE(nullptr, codec) << "Codec must not be null"; ASSERT_NE(nullptr, mockCodec) << "MockCodec must not be null"; codec->stop(); // sleep here so that the looper thread can handle the error std::this_thread::sleep_for(std::chrono::milliseconds(100)); looper->stop(); }
services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h +2 −0 Original line number Diff line number Diff line Loading @@ -438,6 +438,8 @@ public: uint32_t getRecommendedMuteDurationMs() const override; void setTracksInvalidatedStatusByStrategy(product_strategy_t strategy); const sp<IOProfile> mProfile; // I/O profile this output derives from audio_io_handle_t mIoHandle; // output handle uint32_t mLatency; // Loading