Merge "MediaBufferGroup: Fix MediaBufferGroup signal" into oc-dev
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 46a95c5..789eda2 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -67,6 +67,8 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj_arm/SHARED_LIBRARIES/liboboe*)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/mediacodec)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/mediacodec.rc)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/libeffects.so)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib64/libeffects.so)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/include/media/AVSyncSettings.h b/include/media/AVSyncSettings.h
index 4b48419..bbe211f 120000
--- a/include/media/AVSyncSettings.h
+++ b/include/media/AVSyncSettings.h
@@ -1 +1 @@
-../../media/libmedia/include/AVSyncSettings.h
\ No newline at end of file
+../../media/libmedia/include/media/AVSyncSettings.h
\ No newline at end of file
diff --git a/include/media/AudioBufferProvider.h b/include/media/AudioBufferProvider.h
index dd7e234..c4d6e79 120000
--- a/include/media/AudioBufferProvider.h
+++ b/include/media/AudioBufferProvider.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioBufferProvider.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioBufferProvider.h
\ No newline at end of file
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index 343749c..bf52955 120000
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioEffect.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioEffect.h
\ No newline at end of file
diff --git a/include/media/AudioIoDescriptor.h b/include/media/AudioIoDescriptor.h
index 057129b..68f54c9 120000
--- a/include/media/AudioIoDescriptor.h
+++ b/include/media/AudioIoDescriptor.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioIoDescriptor.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioIoDescriptor.h
\ No newline at end of file
diff --git a/include/media/AudioMixer.h b/include/media/AudioMixer.h
index a2d0791..de839c6 120000
--- a/include/media/AudioMixer.h
+++ b/include/media/AudioMixer.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioMixer.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioMixer.h
\ No newline at end of file
diff --git a/include/media/AudioParameter.h b/include/media/AudioParameter.h
index 6b6fe3b..a5889e5 120000
--- a/include/media/AudioParameter.h
+++ b/include/media/AudioParameter.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioParameter.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioParameter.h
\ No newline at end of file
diff --git a/include/media/AudioPolicy.h b/include/media/AudioPolicy.h
index 49ee572..dd4cd53 120000
--- a/include/media/AudioPolicy.h
+++ b/include/media/AudioPolicy.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioPolicy.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioPolicy.h
\ No newline at end of file
diff --git a/include/media/AudioPolicyHelper.h b/include/media/AudioPolicyHelper.h
index a0302e2..558657e 120000
--- a/include/media/AudioPolicyHelper.h
+++ b/include/media/AudioPolicyHelper.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioPolicyHelper.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioPolicyHelper.h
\ No newline at end of file
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index d5a5c36..7939dd3 120000
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioRecord.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioRecord.h
\ No newline at end of file
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 0b7179f..9fad2b7 120000
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioSystem.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioSystem.h
\ No newline at end of file
diff --git a/include/media/AudioTimestamp.h b/include/media/AudioTimestamp.h
index f266780..b6b9278 120000
--- a/include/media/AudioTimestamp.h
+++ b/include/media/AudioTimestamp.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioTimestamp.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioTimestamp.h
\ No newline at end of file
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index fddb075..303bfcd 120000
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -1 +1 @@
-../../media/libaudioclient/include/AudioTrack.h
\ No newline at end of file
+../../media/libaudioclient/include/media/AudioTrack.h
\ No newline at end of file
diff --git a/include/media/BufferProviders.h b/include/media/BufferProviders.h
index a1fd855..779bb15 120000
--- a/include/media/BufferProviders.h
+++ b/include/media/BufferProviders.h
@@ -1 +1 @@
-../../media/libmedia/include/BufferProviders.h
\ No newline at end of file
+../../media/libmedia/include/media/BufferProviders.h
\ No newline at end of file
diff --git a/include/media/BufferingSettings.h b/include/media/BufferingSettings.h
index fb4ec97..409203f 120000
--- a/include/media/BufferingSettings.h
+++ b/include/media/BufferingSettings.h
@@ -1 +1 @@
-../../media/libmedia/include/BufferingSettings.h
\ No newline at end of file
+../../media/libmedia/include/media/BufferingSettings.h
\ No newline at end of file
diff --git a/include/media/CharacterEncodingDetector.h b/include/media/CharacterEncodingDetector.h
index f23ed4c..2b28387 120000
--- a/include/media/CharacterEncodingDetector.h
+++ b/include/media/CharacterEncodingDetector.h
@@ -1 +1 @@
-../../media/libmedia/include/CharacterEncodingDetector.h
\ No newline at end of file
+../../media/libmedia/include/media/CharacterEncodingDetector.h
\ No newline at end of file
diff --git a/include/media/Crypto.h b/include/media/Crypto.h
index 778f6fe..9af6495 120000
--- a/include/media/Crypto.h
+++ b/include/media/Crypto.h
@@ -1 +1 @@
-../../media/libmedia/include/Crypto.h
\ No newline at end of file
+../../media/libmedia/include/media/Crypto.h
\ No newline at end of file
diff --git a/include/media/CryptoHal.h b/include/media/CryptoHal.h
index 81f31f5..92f3137 120000
--- a/include/media/CryptoHal.h
+++ b/include/media/CryptoHal.h
@@ -1 +1 @@
-../../media/libmedia/include/CryptoHal.h
\ No newline at end of file
+../../media/libmedia/include/media/CryptoHal.h
\ No newline at end of file
diff --git a/include/media/Drm.h b/include/media/Drm.h
index d9bfa5c..ac60003 120000
--- a/include/media/Drm.h
+++ b/include/media/Drm.h
@@ -1 +1 @@
-../../media/libmedia/include/Drm.h
\ No newline at end of file
+../../media/libmedia/include/media/Drm.h
\ No newline at end of file
diff --git a/include/media/DrmHal.h b/include/media/DrmHal.h
index 21ba37b..17bb667 120000
--- a/include/media/DrmHal.h
+++ b/include/media/DrmHal.h
@@ -1 +1 @@
-../../media/libmedia/include/DrmHal.h
\ No newline at end of file
+../../media/libmedia/include/media/DrmHal.h
\ No newline at end of file
diff --git a/include/media/DrmPluginPath.h b/include/media/DrmPluginPath.h
index 06b12cf..9e05194 120000
--- a/include/media/DrmPluginPath.h
+++ b/include/media/DrmPluginPath.h
@@ -1 +1 @@
-../../media/libmedia/include/DrmPluginPath.h
\ No newline at end of file
+../../media/libmedia/include/media/DrmPluginPath.h
\ No newline at end of file
diff --git a/include/media/DrmSessionClientInterface.h b/include/media/DrmSessionClientInterface.h
index 72090a3..f4e3211 120000
--- a/include/media/DrmSessionClientInterface.h
+++ b/include/media/DrmSessionClientInterface.h
@@ -1 +1 @@
-../../media/libmedia/include/DrmSessionClientInterface.h
\ No newline at end of file
+../../media/libmedia/include/media/DrmSessionClientInterface.h
\ No newline at end of file
diff --git a/include/media/DrmSessionManager.h b/include/media/DrmSessionManager.h
index 47200f7..f0a47bf 120000
--- a/include/media/DrmSessionManager.h
+++ b/include/media/DrmSessionManager.h
@@ -1 +1 @@
-../../media/libmedia/include/DrmSessionManager.h
\ No newline at end of file
+../../media/libmedia/include/media/DrmSessionManager.h
\ No newline at end of file
diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
index 2431dfb..288590a 120000
--- a/include/media/EffectsFactoryApi.h
+++ b/include/media/EffectsFactoryApi.h
@@ -1 +1 @@
-../../media/libeffects/factory/include/EffectsFactoryApi.h
\ No newline at end of file
+../../media/libeffects/factory/include/media/EffectsFactoryApi.h
\ No newline at end of file
diff --git a/include/media/ExtendedAudioBufferProvider.h b/include/media/ExtendedAudioBufferProvider.h
index 9497be1..d653cc3 120000
--- a/include/media/ExtendedAudioBufferProvider.h
+++ b/include/media/ExtendedAudioBufferProvider.h
@@ -1 +1 @@
-../../media/libmedia/include/ExtendedAudioBufferProvider.h
\ No newline at end of file
+../../media/libmedia/include/media/ExtendedAudioBufferProvider.h
\ No newline at end of file
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
new file mode 120000
index 0000000..ef6f5be
--- /dev/null
+++ b/include/media/IAudioFlinger.h
@@ -0,0 +1 @@
+../../media/libaudioclient/include/media/IAudioFlinger.h
\ No newline at end of file
diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h
index d27389e..dc481e8 120000
--- a/include/media/IAudioFlingerClient.h
+++ b/include/media/IAudioFlingerClient.h
@@ -1 +1 @@
-../../media/libaudioclient/include/IAudioFlingerClient.h
\ No newline at end of file
+../../media/libaudioclient/include/media/IAudioFlingerClient.h
\ No newline at end of file
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 8ef16e2..08101fc 120000
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -1 +1 @@
-../../media/libaudioclient/include/IAudioPolicyService.h
\ No newline at end of file
+../../media/libaudioclient/include/media/IAudioPolicyService.h
\ No newline at end of file
diff --git a/include/media/IAudioPolicyServiceClient.h b/include/media/IAudioPolicyServiceClient.h
index 26f6790..0d4b3e7 120000
--- a/include/media/IAudioPolicyServiceClient.h
+++ b/include/media/IAudioPolicyServiceClient.h
@@ -1 +1 @@
-../../media/libaudioclient/include/IAudioPolicyServiceClient.h
\ No newline at end of file
+../../media/libaudioclient/include/media/IAudioPolicyServiceClient.h
\ No newline at end of file
diff --git a/include/media/IAudioRecord.h b/include/media/IAudioRecord.h
index 520d44e..7fbf8f2 120000
--- a/include/media/IAudioRecord.h
+++ b/include/media/IAudioRecord.h
@@ -1 +1 @@
-../../media/libaudioclient/include/IAudioRecord.h
\ No newline at end of file
+../../media/libaudioclient/include/media/IAudioRecord.h
\ No newline at end of file
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index afa6bf4..7bab1fd 120000
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -1 +1 @@
-../../media/libaudioclient/include/IAudioTrack.h
\ No newline at end of file
+../../media/libaudioclient/include/media/IAudioTrack.h
\ No newline at end of file
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
index 53c547a..b250e07 120000
--- a/include/media/ICrypto.h
+++ b/include/media/ICrypto.h
@@ -1 +1 @@
-../../media/libmedia/include/ICrypto.h
\ No newline at end of file
+../../media/libmedia/include/media/ICrypto.h
\ No newline at end of file
diff --git a/include/media/IDataSource.h b/include/media/IDataSource.h
index 7ac813f..41cdd8b 120000
--- a/include/media/IDataSource.h
+++ b/include/media/IDataSource.h
@@ -1 +1 @@
-../../media/libmedia/include/IDataSource.h
\ No newline at end of file
+../../media/libmedia/include/media/IDataSource.h
\ No newline at end of file
diff --git a/include/media/IDrm.h b/include/media/IDrm.h
index eb2f0ec..841bb1b 120000
--- a/include/media/IDrm.h
+++ b/include/media/IDrm.h
@@ -1 +1 @@
-../../media/libmedia/include/IDrm.h
\ No newline at end of file
+../../media/libmedia/include/media/IDrm.h
\ No newline at end of file
diff --git a/include/media/IDrmClient.h b/include/media/IDrmClient.h
index 4d8b50c..10aa5c0 120000
--- a/include/media/IDrmClient.h
+++ b/include/media/IDrmClient.h
@@ -1 +1 @@
-../../media/libmedia/include/IDrmClient.h
\ No newline at end of file
+../../media/libmedia/include/media/IDrmClient.h
\ No newline at end of file
diff --git a/include/media/IEffect.h b/include/media/IEffect.h
index 72d715d..2fb8bfb 120000
--- a/include/media/IEffect.h
+++ b/include/media/IEffect.h
@@ -1 +1 @@
-../../media/libaudioclient/include/IEffect.h
\ No newline at end of file
+../../media/libaudioclient/include/media/IEffect.h
\ No newline at end of file
diff --git a/include/media/IEffectClient.h b/include/media/IEffectClient.h
index 0614d8a..b4e39cf 120000
--- a/include/media/IEffectClient.h
+++ b/include/media/IEffectClient.h
@@ -1 +1 @@
-../../media/libaudioclient/include/IEffectClient.h
\ No newline at end of file
+../../media/libaudioclient/include/media/IEffectClient.h
\ No newline at end of file
diff --git a/include/media/IHDCP.h b/include/media/IHDCP.h
index f1e112e..9d4568e 120000
--- a/include/media/IHDCP.h
+++ b/include/media/IHDCP.h
@@ -1 +1 @@
-../../media/libmedia/include/IHDCP.h
\ No newline at end of file
+../../media/libmedia/include/media/IHDCP.h
\ No newline at end of file
diff --git a/include/media/IMediaCodecList.h b/include/media/IMediaCodecList.h
index 2e30503..2186312 120000
--- a/include/media/IMediaCodecList.h
+++ b/include/media/IMediaCodecList.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaCodecList.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaCodecList.h
\ No newline at end of file
diff --git a/include/media/IMediaCodecService.h b/include/media/IMediaCodecService.h
index 5103277..37f6822 120000
--- a/include/media/IMediaCodecService.h
+++ b/include/media/IMediaCodecService.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaCodecService.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaCodecService.h
\ No newline at end of file
diff --git a/include/media/IMediaDeathNotifier.h b/include/media/IMediaDeathNotifier.h
index 74b1656..ce3b8f0 120000
--- a/include/media/IMediaDeathNotifier.h
+++ b/include/media/IMediaDeathNotifier.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaDeathNotifier.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaDeathNotifier.h
\ No newline at end of file
diff --git a/include/media/IMediaDrmService.h b/include/media/IMediaDrmService.h
index 6efbc48..f3c260f 120000
--- a/include/media/IMediaDrmService.h
+++ b/include/media/IMediaDrmService.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaDrmService.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaDrmService.h
\ No newline at end of file
diff --git a/include/media/IMediaExtractor.h b/include/media/IMediaExtractor.h
index c17c4eb..8708c8c 120000
--- a/include/media/IMediaExtractor.h
+++ b/include/media/IMediaExtractor.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaExtractor.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaExtractor.h
\ No newline at end of file
diff --git a/include/media/IMediaExtractorService.h b/include/media/IMediaExtractorService.h
index 1e6e8b4..3ee9f1e 120000
--- a/include/media/IMediaExtractorService.h
+++ b/include/media/IMediaExtractorService.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaExtractorService.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaExtractorService.h
\ No newline at end of file
diff --git a/include/media/IMediaHTTPConnection.h b/include/media/IMediaHTTPConnection.h
index 9e544fe..0970c15 120000
--- a/include/media/IMediaHTTPConnection.h
+++ b/include/media/IMediaHTTPConnection.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaHTTPConnection.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaHTTPConnection.h
\ No newline at end of file
diff --git a/include/media/IMediaHTTPService.h b/include/media/IMediaHTTPService.h
index 6312e06..b90c34f 120000
--- a/include/media/IMediaHTTPService.h
+++ b/include/media/IMediaHTTPService.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaHTTPService.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaHTTPService.h
\ No newline at end of file
diff --git a/include/media/IMediaLogService.h b/include/media/IMediaLogService.h
new file mode 120000
index 0000000..245a29d
--- /dev/null
+++ b/include/media/IMediaLogService.h
@@ -0,0 +1 @@
+../../media/libmedia/include/media/IMediaLogService.h
\ No newline at end of file
diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h
index c2dd811..959df1a 120000
--- a/include/media/IMediaMetadataRetriever.h
+++ b/include/media/IMediaMetadataRetriever.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaMetadataRetriever.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaMetadataRetriever.h
\ No newline at end of file
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index a38baf4..9414d37 120000
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaPlayer.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaPlayer.h
\ No newline at end of file
diff --git a/include/media/IMediaPlayerClient.h b/include/media/IMediaPlayerClient.h
index 1c27dee..b6547ce 120000
--- a/include/media/IMediaPlayerClient.h
+++ b/include/media/IMediaPlayerClient.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaPlayerClient.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaPlayerClient.h
\ No newline at end of file
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 08a6a98..89c96cd 120000
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaPlayerService.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaPlayerService.h
\ No newline at end of file
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index c8b8b29..57d192c 120000
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaRecorder.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaRecorder.h
\ No newline at end of file
diff --git a/include/media/IMediaRecorderClient.h b/include/media/IMediaRecorderClient.h
index ab703aa..89f4359 120000
--- a/include/media/IMediaRecorderClient.h
+++ b/include/media/IMediaRecorderClient.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaRecorderClient.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaRecorderClient.h
\ No newline at end of file
diff --git a/include/media/IMediaSource.h b/include/media/IMediaSource.h
index 1c3d8fe..1330ad3 120000
--- a/include/media/IMediaSource.h
+++ b/include/media/IMediaSource.h
@@ -1 +1 @@
-../../media/libmedia/include/IMediaSource.h
\ No newline at end of file
+../../media/libmedia/include/media/IMediaSource.h
\ No newline at end of file
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 989d9b2..6d5b375 120000
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -1 +1 @@
-../../media/libmedia/include/IOMX.h
\ No newline at end of file
+../../media/libmedia/include/media/IOMX.h
\ No newline at end of file
diff --git a/include/media/IRemoteDisplay.h b/include/media/IRemoteDisplay.h
index 5aa58b9..4b0cf10 120000
--- a/include/media/IRemoteDisplay.h
+++ b/include/media/IRemoteDisplay.h
@@ -1 +1 @@
-../../media/libmedia/include/IRemoteDisplay.h
\ No newline at end of file
+../../media/libmedia/include/media/IRemoteDisplay.h
\ No newline at end of file
diff --git a/include/media/IRemoteDisplayClient.h b/include/media/IRemoteDisplayClient.h
index 2d212e7..f29a2ee 120000
--- a/include/media/IRemoteDisplayClient.h
+++ b/include/media/IRemoteDisplayClient.h
@@ -1 +1 @@
-../../media/libmedia/include/IRemoteDisplayClient.h
\ No newline at end of file
+../../media/libmedia/include/media/IRemoteDisplayClient.h
\ No newline at end of file
diff --git a/include/media/IResourceManagerClient.h b/include/media/IResourceManagerClient.h
index 1531ae2..100af9b 120000
--- a/include/media/IResourceManagerClient.h
+++ b/include/media/IResourceManagerClient.h
@@ -1 +1 @@
-../../media/libmedia/include/IResourceManagerClient.h
\ No newline at end of file
+../../media/libmedia/include/media/IResourceManagerClient.h
\ No newline at end of file
diff --git a/include/media/IResourceManagerService.h b/include/media/IResourceManagerService.h
index 007aecb..9b389c6 120000
--- a/include/media/IResourceManagerService.h
+++ b/include/media/IResourceManagerService.h
@@ -1 +1 @@
-../../media/libmedia/include/IResourceManagerService.h
\ No newline at end of file
+../../media/libmedia/include/media/IResourceManagerService.h
\ No newline at end of file
diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h
index 90dbbf2..4943af9 120000
--- a/include/media/IStreamSource.h
+++ b/include/media/IStreamSource.h
@@ -1 +1 @@
-../../media/libmedia/include/IStreamSource.h
\ No newline at end of file
+../../media/libmedia/include/media/IStreamSource.h
\ No newline at end of file
diff --git a/include/media/JetPlayer.h b/include/media/JetPlayer.h
index cabfb79..5483fda 120000
--- a/include/media/JetPlayer.h
+++ b/include/media/JetPlayer.h
@@ -1 +1 @@
-../../media/libmedia/include/JetPlayer.h
\ No newline at end of file
+../../media/libmedia/include/media/JetPlayer.h
\ No newline at end of file
diff --git a/include/media/LinearMap.h b/include/media/LinearMap.h
index 3e89686..30d4ca8 120000
--- a/include/media/LinearMap.h
+++ b/include/media/LinearMap.h
@@ -1 +1 @@
-../../media/libmedia/include/LinearMap.h
\ No newline at end of file
+../../media/libmedia/include/media/LinearMap.h
\ No newline at end of file
diff --git a/include/media/MediaCodecBuffer.h b/include/media/MediaCodecBuffer.h
index 60b7e70..8c9aa76 120000
--- a/include/media/MediaCodecBuffer.h
+++ b/include/media/MediaCodecBuffer.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaCodecBuffer.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaCodecBuffer.h
\ No newline at end of file
diff --git a/include/media/MediaCodecInfo.h b/include/media/MediaCodecInfo.h
index 22b10bb..ff44ce4 120000
--- a/include/media/MediaCodecInfo.h
+++ b/include/media/MediaCodecInfo.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaCodecInfo.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaCodecInfo.h
\ No newline at end of file
diff --git a/include/media/MediaDefs.h b/include/media/MediaDefs.h
index 993729d..9850603 120000
--- a/include/media/MediaDefs.h
+++ b/include/media/MediaDefs.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaDefs.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaDefs.h
\ No newline at end of file
diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h
index a09f9bb..1c53511 120000
--- a/include/media/MediaMetadataRetrieverInterface.h
+++ b/include/media/MediaMetadataRetrieverInterface.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaMetadataRetrieverInterface.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaMetadataRetrieverInterface.h
\ No newline at end of file
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index 86958e4..651c6e6 120000
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaProfiles.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaProfiles.h
\ No newline at end of file
diff --git a/include/media/MediaRecorderBase.h b/include/media/MediaRecorderBase.h
index 6080258..e40f992 120000
--- a/include/media/MediaRecorderBase.h
+++ b/include/media/MediaRecorderBase.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaRecorderBase.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaRecorderBase.h
\ No newline at end of file
diff --git a/include/media/MediaResource.h b/include/media/MediaResource.h
index aaf931a..91346aa 120000
--- a/include/media/MediaResource.h
+++ b/include/media/MediaResource.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaResource.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaResource.h
\ No newline at end of file
diff --git a/include/media/MediaResourcePolicy.h b/include/media/MediaResourcePolicy.h
index d56b09f..5d165ee 120000
--- a/include/media/MediaResourcePolicy.h
+++ b/include/media/MediaResourcePolicy.h
@@ -1 +1 @@
-../../media/libmedia/include/MediaResourcePolicy.h
\ No newline at end of file
+../../media/libmedia/include/media/MediaResourcePolicy.h
\ No newline at end of file
diff --git a/include/media/MemoryLeakTrackUtil.h b/include/media/MemoryLeakTrackUtil.h
index cfeac14..504173e 120000
--- a/include/media/MemoryLeakTrackUtil.h
+++ b/include/media/MemoryLeakTrackUtil.h
@@ -1 +1 @@
-../../media/libmedia/include/MemoryLeakTrackUtil.h
\ No newline at end of file
+../../media/libmedia/include/media/MemoryLeakTrackUtil.h
\ No newline at end of file
diff --git a/include/media/Metadata.h b/include/media/Metadata.h
index 4a5893d..e421168 120000
--- a/include/media/Metadata.h
+++ b/include/media/Metadata.h
@@ -1 +1 @@
-../../media/libmedia/include/Metadata.h
\ No newline at end of file
+../../media/libmedia/include/media/Metadata.h
\ No newline at end of file
diff --git a/include/media/MidiDeviceInfo.h b/include/media/MidiDeviceInfo.h
index 55ac9f5..95da7cf 120000
--- a/include/media/MidiDeviceInfo.h
+++ b/include/media/MidiDeviceInfo.h
@@ -1 +1 @@
-../../media/libmedia/include/MidiDeviceInfo.h
\ No newline at end of file
+../../media/libmedia/include/media/MidiDeviceInfo.h
\ No newline at end of file
diff --git a/include/media/MidiIoWrapper.h b/include/media/MidiIoWrapper.h
index a3fe892..786ec3d 120000
--- a/include/media/MidiIoWrapper.h
+++ b/include/media/MidiIoWrapper.h
@@ -1 +1 @@
-../../media/libmedia/include/MidiIoWrapper.h
\ No newline at end of file
+../../media/libmedia/include/media/MidiIoWrapper.h
\ No newline at end of file
diff --git a/include/media/Modulo.h b/include/media/Modulo.h
index 58f31a4..989c4cb 120000
--- a/include/media/Modulo.h
+++ b/include/media/Modulo.h
@@ -1 +1 @@
-../../media/libmedia/include/Modulo.h
\ No newline at end of file
+../../media/libmedia/include/media/Modulo.h
\ No newline at end of file
diff --git a/include/media/OMXBuffer.h b/include/media/OMXBuffer.h
index 9defe79..00db207 120000
--- a/include/media/OMXBuffer.h
+++ b/include/media/OMXBuffer.h
@@ -1 +1 @@
-../../media/libmedia/include/OMXBuffer.h
\ No newline at end of file
+../../media/libmedia/include/media/OMXBuffer.h
\ No newline at end of file
diff --git a/include/media/OMXFenceParcelable.h b/include/media/OMXFenceParcelable.h
index 2e996dd..c4c1b0a 120000
--- a/include/media/OMXFenceParcelable.h
+++ b/include/media/OMXFenceParcelable.h
@@ -1 +1 @@
-../../media/libmedia/include/OMXFenceParcelable.h
\ No newline at end of file
+../../media/libmedia/include/media/OMXFenceParcelable.h
\ No newline at end of file
diff --git a/include/media/PluginLoader.h b/include/media/PluginLoader.h
index f67f2c4..9101735 120000
--- a/include/media/PluginLoader.h
+++ b/include/media/PluginLoader.h
@@ -1 +1 @@
-../../media/libmedia/include/PluginLoader.h
\ No newline at end of file
+../../media/libmedia/include/media/PluginLoader.h
\ No newline at end of file
diff --git a/include/media/RecordBufferConverter.h b/include/media/RecordBufferConverter.h
index b9ee8df..2d7bc0c 120000
--- a/include/media/RecordBufferConverter.h
+++ b/include/media/RecordBufferConverter.h
@@ -1 +1 @@
-../../media/libmedia/include/RecordBufferConverter.h
\ No newline at end of file
+../../media/libmedia/include/media/RecordBufferConverter.h
\ No newline at end of file
diff --git a/include/media/RingBuffer.h b/include/media/RingBuffer.h
index 84f4943..9af28d5 120000
--- a/include/media/RingBuffer.h
+++ b/include/media/RingBuffer.h
@@ -1 +1 @@
-../../media/libmedia/include/RingBuffer.h
\ No newline at end of file
+../../media/libmedia/include/media/RingBuffer.h
\ No newline at end of file
diff --git a/include/media/SharedLibrary.h b/include/media/SharedLibrary.h
index a2a040f..9f8f5a4 120000
--- a/include/media/SharedLibrary.h
+++ b/include/media/SharedLibrary.h
@@ -1 +1 @@
-../../media/libmedia/include/SharedLibrary.h
\ No newline at end of file
+../../media/libmedia/include/media/SharedLibrary.h
\ No newline at end of file
diff --git a/include/media/SingleStateQueue.h b/include/media/SingleStateQueue.h
index 7dda0d8..619f6ee 120000
--- a/include/media/SingleStateQueue.h
+++ b/include/media/SingleStateQueue.h
@@ -1 +1 @@
-../../media/libmedia/include/SingleStateQueue.h
\ No newline at end of file
+../../media/libmedia/include/media/SingleStateQueue.h
\ No newline at end of file
diff --git a/include/media/StringArray.h b/include/media/StringArray.h
index 5061652..616ce6c 120000
--- a/include/media/StringArray.h
+++ b/include/media/StringArray.h
@@ -1 +1 @@
-../../media/libmedia/include/StringArray.h
\ No newline at end of file
+../../media/libmedia/include/media/StringArray.h
\ No newline at end of file
diff --git a/include/media/ToneGenerator.h b/include/media/ToneGenerator.h
index f00ee2d..33df0e3 120000
--- a/include/media/ToneGenerator.h
+++ b/include/media/ToneGenerator.h
@@ -1 +1 @@
-../../media/libaudioclient/include/ToneGenerator.h
\ No newline at end of file
+../../media/libaudioclient/include/media/ToneGenerator.h
\ No newline at end of file
diff --git a/include/media/TypeConverter.h b/include/media/TypeConverter.h
index 9109aaa..837af44 120000
--- a/include/media/TypeConverter.h
+++ b/include/media/TypeConverter.h
@@ -1 +1 @@
-../../media/libmedia/include/TypeConverter.h
\ No newline at end of file
+../../media/libmedia/include/media/TypeConverter.h
\ No newline at end of file
diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h
index fca8b86..ed2ec15 120000
--- a/include/media/Visualizer.h
+++ b/include/media/Visualizer.h
@@ -1 +1 @@
-../../media/libmedia/include/Visualizer.h
\ No newline at end of file
+../../media/libmedia/include/media/Visualizer.h
\ No newline at end of file
diff --git a/include/media/convert.h b/include/media/convert.h
index 3e09482..cb0d00d 120000
--- a/include/media/convert.h
+++ b/include/media/convert.h
@@ -1 +1 @@
-../../media/libmedia/include/convert.h
\ No newline at end of file
+../../media/libmedia/include/media/convert.h
\ No newline at end of file
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 1992b05..b401bab 120000
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -1 +1 @@
-../../media/libmedia/include/mediametadataretriever.h
\ No newline at end of file
+../../media/libmedia/include/media/mediametadataretriever.h
\ No newline at end of file
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 2b1d298..06d537b 120000
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -1 +1 @@
-../../media/libmedia/include/mediaplayer.h
\ No newline at end of file
+../../media/libmedia/include/media/mediaplayer.h
\ No newline at end of file
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 08c826f..a24deb3 120000
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -1 +1 @@
-../../media/libmedia/include/mediarecorder.h
\ No newline at end of file
+../../media/libmedia/include/media/mediarecorder.h
\ No newline at end of file
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index 42c3507..91479e0 120000
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -1 +1 @@
-../../media/libmedia/include/mediascanner.h
\ No newline at end of file
+../../media/libmedia/include/media/mediascanner.h
\ No newline at end of file
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index ad130e0..166534f 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -1,3 +1,9 @@
+cc_library_headers {
+ name: "libaudioclient_headers",
+ vendor_available: true,
+ export_include_dirs: ["include"],
+}
+
cc_library_shared {
name: "libaudioclient",
srcs: [
@@ -26,17 +32,20 @@
"libaudioutils",
],
export_shared_lib_headers: ["libbinder"],
- local_include_dirs: ["include"],
- export_include_dirs: ["include"],
+
+ local_include_dirs: ["include/media"],
+ header_libs: ["libaudioclient_headers"],
+ export_header_lib_headers: ["libaudioclient_headers"],
+
// for memory heap analysis
static_libs: [
"libc_malloc_debug_backtrace",
"libc_logging",
],
cflags: [
+ "-Wall",
"-Werror",
"-Wno-error=deprecated-declarations",
- "-Wall",
],
sanitize: {
misc_undefined : [
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 4e2a0d5..858b5cc 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -24,7 +24,7 @@
#include <binder/Parcel.h>
-#include <media/IAudioFlinger.h>
+#include "IAudioFlinger.h"
namespace android {
diff --git a/media/libaudioclient/include/IAudioFlinger.h b/media/libaudioclient/include/IAudioFlinger.h
deleted file mode 100644
index 8c5e61a..0000000
--- a/media/libaudioclient/include/IAudioFlinger.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2007 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_IAUDIOFLINGER_H
-#define ANDROID_IAUDIOFLINGER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <utils/RefBase.h>
-#include <utils/Errors.h>
-#include <binder/IInterface.h>
-#include <media/IAudioTrack.h>
-#include <media/IAudioRecord.h>
-#include <media/IAudioFlingerClient.h>
-#include <system/audio.h>
-#include <system/audio_effect.h>
-#include <system/audio_policy.h>
-#include <media/IEffect.h>
-#include <media/IEffectClient.h>
-#include <utils/String8.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IAudioFlinger : public IInterface
-{
-public:
- DECLARE_META_INTERFACE(AudioFlinger);
-
-
- // invariant on exit for all APIs that return an sp<>:
- // (return value != 0) == (*status == NO_ERROR)
-
- /* create an audio track and registers it with AudioFlinger.
- * return null if the track cannot be created.
- */
- virtual sp<IAudioTrack> createTrack(
- audio_stream_type_t streamType,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- size_t *pFrameCount,
- audio_output_flags_t *flags,
- const sp<IMemory>& sharedBuffer,
- // On successful return, AudioFlinger takes over the handle
- // reference and will release it when the track is destroyed.
- // However on failure, the client is responsible for release.
- audio_io_handle_t output,
- pid_t pid,
- pid_t tid, // -1 means unused, otherwise must be valid non-0
- audio_session_t *sessionId,
- int clientUid,
- status_t *status,
- audio_port_handle_t portId) = 0;
-
- virtual sp<IAudioRecord> openRecord(
- // On successful return, AudioFlinger takes over the handle
- // reference and will release it when the track is destroyed.
- // However on failure, the client is responsible for release.
- audio_io_handle_t input,
- uint32_t sampleRate,
- audio_format_t format,
- audio_channel_mask_t channelMask,
- const String16& callingPackage,
- size_t *pFrameCount,
- audio_input_flags_t *flags,
- pid_t pid,
- pid_t tid, // -1 means unused, otherwise must be valid non-0
- int clientUid,
- audio_session_t *sessionId,
- size_t *notificationFrames,
- sp<IMemory>& cblk,
- sp<IMemory>& buffers, // return value 0 means it follows cblk
- status_t *status,
- audio_port_handle_t portId) = 0;
-
- // FIXME Surprisingly, format/latency don't work for input handles
-
- /* query the audio hardware state. This state never changes,
- * and therefore can be cached.
- */
- virtual uint32_t sampleRate(audio_io_handle_t ioHandle) const = 0;
-
- // reserved; formerly channelCount()
-
- virtual audio_format_t format(audio_io_handle_t output) const = 0;
- virtual size_t frameCount(audio_io_handle_t ioHandle) const = 0;
-
- // return estimated latency in milliseconds
- virtual uint32_t latency(audio_io_handle_t output) const = 0;
-
- /* set/get the audio hardware state. This will probably be used by
- * the preference panel, mostly.
- */
- virtual status_t setMasterVolume(float value) = 0;
- virtual status_t setMasterMute(bool muted) = 0;
-
- virtual float masterVolume() const = 0;
- virtual bool masterMute() const = 0;
-
- /* set/get stream type state. This will probably be used by
- * the preference panel, mostly.
- */
- virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
- audio_io_handle_t output) = 0;
- virtual status_t setStreamMute(audio_stream_type_t stream, bool muted) = 0;
-
- virtual float streamVolume(audio_stream_type_t stream,
- audio_io_handle_t output) const = 0;
- virtual bool streamMute(audio_stream_type_t stream) const = 0;
-
- // set audio mode
- virtual status_t setMode(audio_mode_t mode) = 0;
-
- // mic mute/state
- virtual status_t setMicMute(bool state) = 0;
- virtual bool getMicMute() const = 0;
-
- virtual status_t setParameters(audio_io_handle_t ioHandle,
- const String8& keyValuePairs) = 0;
- virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys)
- const = 0;
-
- // Register an object to receive audio input/output change and track notifications.
- // For a given calling pid, AudioFlinger disregards any registrations after the first.
- // Thus the IAudioFlingerClient must be a singleton per process.
- virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0;
-
- // retrieve the audio recording buffer size
- // FIXME This API assumes a route, and so should be deprecated.
- virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
- audio_channel_mask_t channelMask) const = 0;
-
- virtual status_t openOutput(audio_module_handle_t module,
- audio_io_handle_t *output,
- audio_config_t *config,
- audio_devices_t *devices,
- const String8& address,
- uint32_t *latencyMs,
- audio_output_flags_t flags) = 0;
- virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
- audio_io_handle_t output2) = 0;
- virtual status_t closeOutput(audio_io_handle_t output) = 0;
- virtual status_t suspendOutput(audio_io_handle_t output) = 0;
- virtual status_t restoreOutput(audio_io_handle_t output) = 0;
-
- virtual status_t openInput(audio_module_handle_t module,
- audio_io_handle_t *input,
- audio_config_t *config,
- audio_devices_t *device,
- const String8& address,
- audio_source_t source,
- audio_input_flags_t flags) = 0;
- virtual status_t closeInput(audio_io_handle_t input) = 0;
-
- virtual status_t invalidateStream(audio_stream_type_t stream) = 0;
-
- virtual status_t setVoiceVolume(float volume) = 0;
-
- virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
- audio_io_handle_t output) const = 0;
-
- virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
-
- virtual audio_unique_id_t newAudioUniqueId(audio_unique_id_use_t use) = 0;
-
- virtual void acquireAudioSessionId(audio_session_t audioSession, pid_t pid) = 0;
- virtual void releaseAudioSessionId(audio_session_t audioSession, pid_t pid) = 0;
-
- virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0;
-
- virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const = 0;
-
- virtual status_t getEffectDescriptor(const effect_uuid_t *pEffectUUID,
- effect_descriptor_t *pDescriptor) const = 0;
-
- virtual sp<IEffect> createEffect(
- effect_descriptor_t *pDesc,
- const sp<IEffectClient>& client,
- int32_t priority,
- // AudioFlinger doesn't take over handle reference from client
- audio_io_handle_t output,
- audio_session_t sessionId,
- const String16& callingPackage,
- pid_t pid,
- status_t *status,
- int *id,
- int *enabled) = 0;
-
- virtual status_t moveEffects(audio_session_t session, audio_io_handle_t srcOutput,
- audio_io_handle_t dstOutput) = 0;
-
- virtual audio_module_handle_t loadHwModule(const char *name) = 0;
-
- // helpers for android.media.AudioManager.getProperty(), see description there for meaning
- // FIXME move these APIs to AudioPolicy to permit a more accurate implementation
- // that looks on primary device for a stream with fast flag, primary flag, or first one.
- virtual uint32_t getPrimaryOutputSamplingRate() = 0;
- virtual size_t getPrimaryOutputFrameCount() = 0;
-
- // Intended for AudioService to inform AudioFlinger of device's low RAM attribute,
- // and should be called at most once. For a definition of what "low RAM" means, see
- // android.app.ActivityManager.isLowRamDevice().
- virtual status_t setLowRamDevice(bool isLowRamDevice) = 0;
-
- /* List available audio ports and their attributes */
- virtual status_t listAudioPorts(unsigned int *num_ports,
- struct audio_port *ports) = 0;
-
- /* Get attributes for a given audio port */
- virtual status_t getAudioPort(struct audio_port *port) = 0;
-
- /* Create an audio patch between several source and sink ports */
- virtual status_t createAudioPatch(const struct audio_patch *patch,
- audio_patch_handle_t *handle) = 0;
-
- /* Release an audio patch */
- virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0;
-
- /* List existing audio patches */
- virtual status_t listAudioPatches(unsigned int *num_patches,
- struct audio_patch *patches) = 0;
- /* Set audio port configuration */
- virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
-
- /* Get the HW synchronization source used for an audio session */
- virtual audio_hw_sync_t getAudioHwSyncForSession(audio_session_t sessionId) = 0;
-
- /* Indicate JAVA services are ready (scheduling, power management ...) */
- virtual status_t systemReady() = 0;
-
- // Returns the number of frames per audio HAL buffer.
- virtual size_t frameCountHAL(audio_io_handle_t ioHandle) const = 0;
-};
-
-
-// ----------------------------------------------------------------------------
-
-class BnAudioFlinger : public BnInterface<IAudioFlinger>
-{
-public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_IAUDIOFLINGER_H
diff --git a/media/libaudioclient/include/AudioBufferProvider.h b/media/libaudioclient/include/media/AudioBufferProvider.h
similarity index 100%
rename from media/libaudioclient/include/AudioBufferProvider.h
rename to media/libaudioclient/include/media/AudioBufferProvider.h
diff --git a/media/libaudioclient/include/AudioEffect.h b/media/libaudioclient/include/media/AudioEffect.h
similarity index 100%
rename from media/libaudioclient/include/AudioEffect.h
rename to media/libaudioclient/include/media/AudioEffect.h
diff --git a/media/libaudioclient/include/AudioIoDescriptor.h b/media/libaudioclient/include/media/AudioIoDescriptor.h
similarity index 100%
rename from media/libaudioclient/include/AudioIoDescriptor.h
rename to media/libaudioclient/include/media/AudioIoDescriptor.h
diff --git a/media/libaudioclient/include/AudioMixer.h b/media/libaudioclient/include/media/AudioMixer.h
similarity index 100%
rename from media/libaudioclient/include/AudioMixer.h
rename to media/libaudioclient/include/media/AudioMixer.h
diff --git a/media/libaudioclient/include/AudioParameter.h b/media/libaudioclient/include/media/AudioParameter.h
similarity index 100%
rename from media/libaudioclient/include/AudioParameter.h
rename to media/libaudioclient/include/media/AudioParameter.h
diff --git a/media/libaudioclient/include/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
similarity index 100%
rename from media/libaudioclient/include/AudioPolicy.h
rename to media/libaudioclient/include/media/AudioPolicy.h
diff --git a/media/libaudioclient/include/AudioPolicyHelper.h b/media/libaudioclient/include/media/AudioPolicyHelper.h
similarity index 96%
rename from media/libaudioclient/include/AudioPolicyHelper.h
rename to media/libaudioclient/include/media/AudioPolicyHelper.h
index 04f6a20..854057d 100644
--- a/media/libaudioclient/include/AudioPolicyHelper.h
+++ b/media/libaudioclient/include/media/AudioPolicyHelper.h
@@ -18,6 +18,8 @@
#include <system/audio.h>
+// TODO: fix this among dependencies
+__attribute__((unused))
static audio_stream_type_t audio_attributes_to_stream_type(const audio_attributes_t *attr)
{
// flags to stream type mapping
@@ -63,6 +65,8 @@
}
}
+// TODO: fix this among dependencies
+__attribute__((unused))
static void stream_type_to_audio_attributes(audio_stream_type_t streamType,
audio_attributes_t *attr) {
memset(attr, 0, sizeof(audio_attributes_t));
diff --git a/media/libaudioclient/include/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
similarity index 100%
rename from media/libaudioclient/include/AudioRecord.h
rename to media/libaudioclient/include/media/AudioRecord.h
diff --git a/media/libaudioclient/include/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
similarity index 100%
rename from media/libaudioclient/include/AudioSystem.h
rename to media/libaudioclient/include/media/AudioSystem.h
diff --git a/media/libaudioclient/include/AudioTimestamp.h b/media/libaudioclient/include/media/AudioTimestamp.h
similarity index 100%
rename from media/libaudioclient/include/AudioTimestamp.h
rename to media/libaudioclient/include/media/AudioTimestamp.h
diff --git a/media/libaudioclient/include/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
similarity index 100%
rename from media/libaudioclient/include/AudioTrack.h
rename to media/libaudioclient/include/media/AudioTrack.h
diff --git a/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
similarity index 100%
rename from include/media/IAudioFlinger.h
rename to media/libaudioclient/include/media/IAudioFlinger.h
diff --git a/media/libaudioclient/include/IAudioFlingerClient.h b/media/libaudioclient/include/media/IAudioFlingerClient.h
similarity index 100%
rename from media/libaudioclient/include/IAudioFlingerClient.h
rename to media/libaudioclient/include/media/IAudioFlingerClient.h
diff --git a/media/libaudioclient/include/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
similarity index 100%
rename from media/libaudioclient/include/IAudioPolicyService.h
rename to media/libaudioclient/include/media/IAudioPolicyService.h
diff --git a/media/libaudioclient/include/IAudioPolicyServiceClient.h b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
similarity index 100%
rename from media/libaudioclient/include/IAudioPolicyServiceClient.h
rename to media/libaudioclient/include/media/IAudioPolicyServiceClient.h
diff --git a/media/libaudioclient/include/IAudioRecord.h b/media/libaudioclient/include/media/IAudioRecord.h
similarity index 100%
rename from media/libaudioclient/include/IAudioRecord.h
rename to media/libaudioclient/include/media/IAudioRecord.h
diff --git a/media/libaudioclient/include/IAudioTrack.h b/media/libaudioclient/include/media/IAudioTrack.h
similarity index 100%
rename from media/libaudioclient/include/IAudioTrack.h
rename to media/libaudioclient/include/media/IAudioTrack.h
diff --git a/media/libaudioclient/include/IEffect.h b/media/libaudioclient/include/media/IEffect.h
similarity index 100%
rename from media/libaudioclient/include/IEffect.h
rename to media/libaudioclient/include/media/IEffect.h
diff --git a/media/libaudioclient/include/IEffectClient.h b/media/libaudioclient/include/media/IEffectClient.h
similarity index 100%
rename from media/libaudioclient/include/IEffectClient.h
rename to media/libaudioclient/include/media/IEffectClient.h
diff --git a/media/libaudioclient/include/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
similarity index 100%
rename from media/libaudioclient/include/ToneGenerator.h
rename to media/libaudioclient/include/media/ToneGenerator.h
diff --git a/media/libeffects/factory/Android.bp b/media/libeffects/factory/Android.bp
index e0e0d13..16680bd 100644
--- a/media/libeffects/factory/Android.bp
+++ b/media/libeffects/factory/Android.bp
@@ -1,6 +1,15 @@
+cc_library_headers {
+ name: "libeffects_headers",
+ vendor_available: true,
+ export_include_dirs: ["include"],
+ header_libs: ["libhardware_headers"],
+ export_header_lib_headers: ["libhardware_headers"],
+}
+
// Effect factory library
cc_library_shared {
name: "libeffects",
+ vendor: true,
srcs: ["EffectsFactory.c"],
shared_libs: [
@@ -11,7 +20,8 @@
include_dirs: ["system/media/audio_effects/include"],
- local_include_dirs:["include"],
+ local_include_dirs:["include/media"],
- export_include_dirs: ["include"],
+ header_libs: ["libeffects_headers"],
+ export_header_lib_headers: ["libeffects_headers"],
}
diff --git a/media/libeffects/factory/include/EffectsFactoryApi.h b/media/libeffects/factory/include/media/EffectsFactoryApi.h
similarity index 100%
rename from media/libeffects/factory/include/EffectsFactoryApi.h
rename to media/libeffects/factory/include/media/EffectsFactoryApi.h
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 772555d..11a498d 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -6,6 +6,7 @@
cc_library {
name: "libmedia_helper",
+ vendor_available: true,
srcs: ["AudioParameter.cpp", "TypeConverter.cpp"],
cflags: [
"-Werror",
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index b0bd22e..e2d48a2 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -86,6 +86,8 @@
android.hardware.media.omx@1.0 \
android.hidl.memory@1.0 \
+LOCAL_HEADER_LIBRARIES := libmedia_headers
+
# for memory heap analysis
LOCAL_STATIC_LIBRARIES := libc_malloc_debug_backtrace libc_logging
diff --git a/media/libmedia/include/IMediaLogService.h b/media/libmedia/include/IMediaLogService.h
deleted file mode 100644
index 1f5777e..0000000
--- a/media/libmedia/include/IMediaLogService.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 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_IMEDIALOGSERVICE_H
-#define ANDROID_IMEDIALOGSERVICE_H
-
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-class IMediaLogService: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(MediaLogService);
-
- virtual void registerWriter(const sp<IMemory>& shared, size_t size, const char *name) = 0;
- virtual void unregisterWriter(const sp<IMemory>& shared) = 0;
-
-};
-
-class BnMediaLogService: public BnInterface<IMediaLogService>
-{
-public:
- virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags = 0);
-};
-
-} // namespace android
-
-#endif // ANDROID_IMEDIALOGSERVICE_H
diff --git a/media/libmedia/include/AVSyncSettings.h b/media/libmedia/include/media/AVSyncSettings.h
similarity index 100%
rename from media/libmedia/include/AVSyncSettings.h
rename to media/libmedia/include/media/AVSyncSettings.h
diff --git a/media/libmedia/include/BufferProviders.h b/media/libmedia/include/media/BufferProviders.h
similarity index 100%
rename from media/libmedia/include/BufferProviders.h
rename to media/libmedia/include/media/BufferProviders.h
diff --git a/media/libmedia/include/BufferingSettings.h b/media/libmedia/include/media/BufferingSettings.h
similarity index 100%
rename from media/libmedia/include/BufferingSettings.h
rename to media/libmedia/include/media/BufferingSettings.h
diff --git a/media/libmedia/include/CharacterEncodingDetector.h b/media/libmedia/include/media/CharacterEncodingDetector.h
similarity index 100%
rename from media/libmedia/include/CharacterEncodingDetector.h
rename to media/libmedia/include/media/CharacterEncodingDetector.h
diff --git a/media/libmedia/include/Crypto.h b/media/libmedia/include/media/Crypto.h
similarity index 100%
rename from media/libmedia/include/Crypto.h
rename to media/libmedia/include/media/Crypto.h
diff --git a/media/libmedia/include/CryptoHal.h b/media/libmedia/include/media/CryptoHal.h
similarity index 100%
rename from media/libmedia/include/CryptoHal.h
rename to media/libmedia/include/media/CryptoHal.h
diff --git a/media/libmedia/include/Drm.h b/media/libmedia/include/media/Drm.h
similarity index 100%
rename from media/libmedia/include/Drm.h
rename to media/libmedia/include/media/Drm.h
diff --git a/media/libmedia/include/DrmHal.h b/media/libmedia/include/media/DrmHal.h
similarity index 100%
rename from media/libmedia/include/DrmHal.h
rename to media/libmedia/include/media/DrmHal.h
diff --git a/media/libmedia/include/DrmPluginPath.h b/media/libmedia/include/media/DrmPluginPath.h
similarity index 100%
rename from media/libmedia/include/DrmPluginPath.h
rename to media/libmedia/include/media/DrmPluginPath.h
diff --git a/media/libmedia/include/DrmSessionClientInterface.h b/media/libmedia/include/media/DrmSessionClientInterface.h
similarity index 100%
rename from media/libmedia/include/DrmSessionClientInterface.h
rename to media/libmedia/include/media/DrmSessionClientInterface.h
diff --git a/media/libmedia/include/DrmSessionManager.h b/media/libmedia/include/media/DrmSessionManager.h
similarity index 100%
rename from media/libmedia/include/DrmSessionManager.h
rename to media/libmedia/include/media/DrmSessionManager.h
diff --git a/media/libmedia/include/ExtendedAudioBufferProvider.h b/media/libmedia/include/media/ExtendedAudioBufferProvider.h
similarity index 100%
rename from media/libmedia/include/ExtendedAudioBufferProvider.h
rename to media/libmedia/include/media/ExtendedAudioBufferProvider.h
diff --git a/media/libmedia/include/ICrypto.h b/media/libmedia/include/media/ICrypto.h
similarity index 100%
rename from media/libmedia/include/ICrypto.h
rename to media/libmedia/include/media/ICrypto.h
diff --git a/media/libmedia/include/IDataSource.h b/media/libmedia/include/media/IDataSource.h
similarity index 100%
rename from media/libmedia/include/IDataSource.h
rename to media/libmedia/include/media/IDataSource.h
diff --git a/media/libmedia/include/IDrm.h b/media/libmedia/include/media/IDrm.h
similarity index 100%
rename from media/libmedia/include/IDrm.h
rename to media/libmedia/include/media/IDrm.h
diff --git a/media/libmedia/include/IDrmClient.h b/media/libmedia/include/media/IDrmClient.h
similarity index 100%
rename from media/libmedia/include/IDrmClient.h
rename to media/libmedia/include/media/IDrmClient.h
diff --git a/media/libmedia/include/IHDCP.h b/media/libmedia/include/media/IHDCP.h
similarity index 100%
rename from media/libmedia/include/IHDCP.h
rename to media/libmedia/include/media/IHDCP.h
diff --git a/media/libmedia/include/IMediaCodecList.h b/media/libmedia/include/media/IMediaCodecList.h
similarity index 100%
rename from media/libmedia/include/IMediaCodecList.h
rename to media/libmedia/include/media/IMediaCodecList.h
diff --git a/media/libmedia/include/IMediaCodecService.h b/media/libmedia/include/media/IMediaCodecService.h
similarity index 100%
rename from media/libmedia/include/IMediaCodecService.h
rename to media/libmedia/include/media/IMediaCodecService.h
diff --git a/media/libmedia/include/IMediaDeathNotifier.h b/media/libmedia/include/media/IMediaDeathNotifier.h
similarity index 100%
rename from media/libmedia/include/IMediaDeathNotifier.h
rename to media/libmedia/include/media/IMediaDeathNotifier.h
diff --git a/media/libmedia/include/IMediaDrmService.h b/media/libmedia/include/media/IMediaDrmService.h
similarity index 100%
rename from media/libmedia/include/IMediaDrmService.h
rename to media/libmedia/include/media/IMediaDrmService.h
diff --git a/media/libmedia/include/IMediaExtractor.h b/media/libmedia/include/media/IMediaExtractor.h
similarity index 100%
rename from media/libmedia/include/IMediaExtractor.h
rename to media/libmedia/include/media/IMediaExtractor.h
diff --git a/media/libmedia/include/IMediaExtractorService.h b/media/libmedia/include/media/IMediaExtractorService.h
similarity index 100%
rename from media/libmedia/include/IMediaExtractorService.h
rename to media/libmedia/include/media/IMediaExtractorService.h
diff --git a/media/libmedia/include/IMediaHTTPConnection.h b/media/libmedia/include/media/IMediaHTTPConnection.h
similarity index 100%
rename from media/libmedia/include/IMediaHTTPConnection.h
rename to media/libmedia/include/media/IMediaHTTPConnection.h
diff --git a/media/libmedia/include/IMediaHTTPService.h b/media/libmedia/include/media/IMediaHTTPService.h
similarity index 100%
rename from media/libmedia/include/IMediaHTTPService.h
rename to media/libmedia/include/media/IMediaHTTPService.h
diff --git a/include/media/IMediaLogService.h b/media/libmedia/include/media/IMediaLogService.h
similarity index 99%
rename from include/media/IMediaLogService.h
rename to media/libmedia/include/media/IMediaLogService.h
index 0f09e0d..1df1907 100644
--- a/include/media/IMediaLogService.h
+++ b/media/libmedia/include/media/IMediaLogService.h
@@ -30,8 +30,8 @@
virtual void registerWriter(const sp<IMemory>& shared, size_t size, const char *name) = 0;
virtual void unregisterWriter(const sp<IMemory>& shared) = 0;
- virtual void requestMergeWakeup() = 0;
+ virtual void requestMergeWakeup() = 0;
};
class BnMediaLogService: public BnInterface<IMediaLogService>
diff --git a/media/libmedia/include/IMediaMetadataRetriever.h b/media/libmedia/include/media/IMediaMetadataRetriever.h
similarity index 100%
rename from media/libmedia/include/IMediaMetadataRetriever.h
rename to media/libmedia/include/media/IMediaMetadataRetriever.h
diff --git a/media/libmedia/include/IMediaPlayer.h b/media/libmedia/include/media/IMediaPlayer.h
similarity index 100%
rename from media/libmedia/include/IMediaPlayer.h
rename to media/libmedia/include/media/IMediaPlayer.h
diff --git a/media/libmedia/include/IMediaPlayerClient.h b/media/libmedia/include/media/IMediaPlayerClient.h
similarity index 100%
rename from media/libmedia/include/IMediaPlayerClient.h
rename to media/libmedia/include/media/IMediaPlayerClient.h
diff --git a/media/libmedia/include/IMediaPlayerService.h b/media/libmedia/include/media/IMediaPlayerService.h
similarity index 100%
rename from media/libmedia/include/IMediaPlayerService.h
rename to media/libmedia/include/media/IMediaPlayerService.h
diff --git a/media/libmedia/include/IMediaRecorder.h b/media/libmedia/include/media/IMediaRecorder.h
similarity index 100%
rename from media/libmedia/include/IMediaRecorder.h
rename to media/libmedia/include/media/IMediaRecorder.h
diff --git a/media/libmedia/include/IMediaRecorderClient.h b/media/libmedia/include/media/IMediaRecorderClient.h
similarity index 100%
rename from media/libmedia/include/IMediaRecorderClient.h
rename to media/libmedia/include/media/IMediaRecorderClient.h
diff --git a/media/libmedia/include/IMediaSource.h b/media/libmedia/include/media/IMediaSource.h
similarity index 100%
rename from media/libmedia/include/IMediaSource.h
rename to media/libmedia/include/media/IMediaSource.h
diff --git a/media/libmedia/include/IOMX.h b/media/libmedia/include/media/IOMX.h
similarity index 100%
rename from media/libmedia/include/IOMX.h
rename to media/libmedia/include/media/IOMX.h
diff --git a/media/libmedia/include/IRemoteDisplay.h b/media/libmedia/include/media/IRemoteDisplay.h
similarity index 100%
rename from media/libmedia/include/IRemoteDisplay.h
rename to media/libmedia/include/media/IRemoteDisplay.h
diff --git a/media/libmedia/include/IRemoteDisplayClient.h b/media/libmedia/include/media/IRemoteDisplayClient.h
similarity index 100%
rename from media/libmedia/include/IRemoteDisplayClient.h
rename to media/libmedia/include/media/IRemoteDisplayClient.h
diff --git a/media/libmedia/include/IResourceManagerClient.h b/media/libmedia/include/media/IResourceManagerClient.h
similarity index 100%
rename from media/libmedia/include/IResourceManagerClient.h
rename to media/libmedia/include/media/IResourceManagerClient.h
diff --git a/media/libmedia/include/IResourceManagerService.h b/media/libmedia/include/media/IResourceManagerService.h
similarity index 100%
rename from media/libmedia/include/IResourceManagerService.h
rename to media/libmedia/include/media/IResourceManagerService.h
diff --git a/media/libmedia/include/IStreamSource.h b/media/libmedia/include/media/IStreamSource.h
similarity index 100%
rename from media/libmedia/include/IStreamSource.h
rename to media/libmedia/include/media/IStreamSource.h
diff --git a/media/libmedia/include/JetPlayer.h b/media/libmedia/include/media/JetPlayer.h
similarity index 100%
rename from media/libmedia/include/JetPlayer.h
rename to media/libmedia/include/media/JetPlayer.h
diff --git a/media/libmedia/include/LinearMap.h b/media/libmedia/include/media/LinearMap.h
similarity index 100%
rename from media/libmedia/include/LinearMap.h
rename to media/libmedia/include/media/LinearMap.h
diff --git a/media/libmedia/include/MediaCodecBuffer.h b/media/libmedia/include/media/MediaCodecBuffer.h
similarity index 100%
rename from media/libmedia/include/MediaCodecBuffer.h
rename to media/libmedia/include/media/MediaCodecBuffer.h
diff --git a/media/libmedia/include/MediaCodecInfo.h b/media/libmedia/include/media/MediaCodecInfo.h
similarity index 100%
rename from media/libmedia/include/MediaCodecInfo.h
rename to media/libmedia/include/media/MediaCodecInfo.h
diff --git a/media/libmedia/include/MediaDefs.h b/media/libmedia/include/media/MediaDefs.h
similarity index 100%
rename from media/libmedia/include/MediaDefs.h
rename to media/libmedia/include/media/MediaDefs.h
diff --git a/media/libmedia/include/MediaMetadataRetrieverInterface.h b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
similarity index 100%
rename from media/libmedia/include/MediaMetadataRetrieverInterface.h
rename to media/libmedia/include/media/MediaMetadataRetrieverInterface.h
diff --git a/media/libmedia/include/MediaProfiles.h b/media/libmedia/include/media/MediaProfiles.h
similarity index 100%
rename from media/libmedia/include/MediaProfiles.h
rename to media/libmedia/include/media/MediaProfiles.h
diff --git a/media/libmedia/include/MediaRecorderBase.h b/media/libmedia/include/media/MediaRecorderBase.h
similarity index 100%
rename from media/libmedia/include/MediaRecorderBase.h
rename to media/libmedia/include/media/MediaRecorderBase.h
diff --git a/media/libmedia/include/MediaResource.h b/media/libmedia/include/media/MediaResource.h
similarity index 100%
rename from media/libmedia/include/MediaResource.h
rename to media/libmedia/include/media/MediaResource.h
diff --git a/media/libmedia/include/MediaResourcePolicy.h b/media/libmedia/include/media/MediaResourcePolicy.h
similarity index 100%
rename from media/libmedia/include/MediaResourcePolicy.h
rename to media/libmedia/include/media/MediaResourcePolicy.h
diff --git a/media/libmedia/include/MemoryLeakTrackUtil.h b/media/libmedia/include/media/MemoryLeakTrackUtil.h
similarity index 100%
rename from media/libmedia/include/MemoryLeakTrackUtil.h
rename to media/libmedia/include/media/MemoryLeakTrackUtil.h
diff --git a/media/libmedia/include/Metadata.h b/media/libmedia/include/media/Metadata.h
similarity index 100%
rename from media/libmedia/include/Metadata.h
rename to media/libmedia/include/media/Metadata.h
diff --git a/media/libmedia/include/MidiDeviceInfo.h b/media/libmedia/include/media/MidiDeviceInfo.h
similarity index 100%
rename from media/libmedia/include/MidiDeviceInfo.h
rename to media/libmedia/include/media/MidiDeviceInfo.h
diff --git a/media/libmedia/include/MidiIoWrapper.h b/media/libmedia/include/media/MidiIoWrapper.h
similarity index 100%
rename from media/libmedia/include/MidiIoWrapper.h
rename to media/libmedia/include/media/MidiIoWrapper.h
diff --git a/media/libmedia/include/Modulo.h b/media/libmedia/include/media/Modulo.h
similarity index 100%
rename from media/libmedia/include/Modulo.h
rename to media/libmedia/include/media/Modulo.h
diff --git a/media/libmedia/include/OMXBuffer.h b/media/libmedia/include/media/OMXBuffer.h
similarity index 100%
rename from media/libmedia/include/OMXBuffer.h
rename to media/libmedia/include/media/OMXBuffer.h
diff --git a/media/libmedia/include/OMXFenceParcelable.h b/media/libmedia/include/media/OMXFenceParcelable.h
similarity index 100%
rename from media/libmedia/include/OMXFenceParcelable.h
rename to media/libmedia/include/media/OMXFenceParcelable.h
diff --git a/media/libmedia/include/PluginLoader.h b/media/libmedia/include/media/PluginLoader.h
similarity index 100%
rename from media/libmedia/include/PluginLoader.h
rename to media/libmedia/include/media/PluginLoader.h
diff --git a/media/libmedia/include/RecordBufferConverter.h b/media/libmedia/include/media/RecordBufferConverter.h
similarity index 100%
rename from media/libmedia/include/RecordBufferConverter.h
rename to media/libmedia/include/media/RecordBufferConverter.h
diff --git a/media/libmedia/include/RingBuffer.h b/media/libmedia/include/media/RingBuffer.h
similarity index 100%
rename from media/libmedia/include/RingBuffer.h
rename to media/libmedia/include/media/RingBuffer.h
diff --git a/media/libmedia/include/SharedLibrary.h b/media/libmedia/include/media/SharedLibrary.h
similarity index 100%
rename from media/libmedia/include/SharedLibrary.h
rename to media/libmedia/include/media/SharedLibrary.h
diff --git a/media/libmedia/include/SingleStateQueue.h b/media/libmedia/include/media/SingleStateQueue.h
similarity index 100%
rename from media/libmedia/include/SingleStateQueue.h
rename to media/libmedia/include/media/SingleStateQueue.h
diff --git a/media/libmedia/include/StringArray.h b/media/libmedia/include/media/StringArray.h
similarity index 100%
rename from media/libmedia/include/StringArray.h
rename to media/libmedia/include/media/StringArray.h
diff --git a/media/libmedia/include/TypeConverter.h b/media/libmedia/include/media/TypeConverter.h
similarity index 99%
rename from media/libmedia/include/TypeConverter.h
rename to media/libmedia/include/media/TypeConverter.h
index e262eef..cb8a307 100644
--- a/media/libmedia/include/TypeConverter.h
+++ b/media/libmedia/include/media/TypeConverter.h
@@ -25,8 +25,8 @@
#include <utils/Vector.h>
#include <utils/SortedVector.h>
+#include <media/AudioParameter.h>
#include "convert.h"
-#include "AudioParameter.h"
namespace android {
diff --git a/media/libmedia/include/Visualizer.h b/media/libmedia/include/media/Visualizer.h
similarity index 100%
rename from media/libmedia/include/Visualizer.h
rename to media/libmedia/include/media/Visualizer.h
diff --git a/media/libmedia/include/convert.h b/media/libmedia/include/media/convert.h
similarity index 100%
rename from media/libmedia/include/convert.h
rename to media/libmedia/include/media/convert.h
diff --git a/media/libmedia/include/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
similarity index 100%
rename from media/libmedia/include/mediametadataretriever.h
rename to media/libmedia/include/media/mediametadataretriever.h
diff --git a/media/libmedia/include/mediaplayer.h b/media/libmedia/include/media/mediaplayer.h
similarity index 100%
rename from media/libmedia/include/mediaplayer.h
rename to media/libmedia/include/media/mediaplayer.h
diff --git a/media/libmedia/include/mediarecorder.h b/media/libmedia/include/media/mediarecorder.h
similarity index 100%
rename from media/libmedia/include/mediarecorder.h
rename to media/libmedia/include/media/mediarecorder.h
diff --git a/media/libmedia/include/mediascanner.h b/media/libmedia/include/media/mediascanner.h
similarity index 100%
rename from media/libmedia/include/mediascanner.h
rename to media/libmedia/include/media/mediascanner.h
diff --git a/media/libnbaio/PipeReader.cpp b/media/libnbaio/PipeReader.cpp
index be5c0c1..2486b76 100644
--- a/media/libnbaio/PipeReader.cpp
+++ b/media/libnbaio/PipeReader.cpp
@@ -26,7 +26,7 @@
PipeReader::PipeReader(Pipe& pipe) :
NBAIO_Source(pipe.mFormat),
- mPipe(pipe), mFifoReader(mPipe.mFifo, false /*throttlesWriter*/),
+ mPipe(pipe), mFifoReader(mPipe.mFifo, false /*throttlesWriter*/, true /*flush*/),
mFramesOverrun(0),
mOverruns(0)
{
diff --git a/media/libstagefright/include/foundation/ADebug.h b/media/libstagefright/include/foundation/ADebug.h
index 564b3f7..9ad45f3 100644
--- a/media/libstagefright/include/foundation/ADebug.h
+++ b/media/libstagefright/include/foundation/ADebug.h
@@ -99,10 +99,30 @@
#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
-#define TRESPASS() \
+#define TRESPASS(...) \
LOG_ALWAYS_FATAL( \
__FILE__ ":" LITERAL_TO_STRING(__LINE__) \
- " Should not be here.");
+ " Should not be here. " __VA_ARGS__);
+
+#ifdef NDEBUG
+#define CHECK_DBG CHECK
+#define CHECK_EQ_DBG CHECK_EQ
+#define CHECK_NE_DBG CHECK_NE
+#define CHECK_LE_DBG CHECK_LE
+#define CHECK_LT_DBG CHECK_LT
+#define CHECK_GE_DBG CHECK_GE
+#define CHECK_GT_DBG CHECK_GT
+#define TRESPASS_DBG TRESPASS
+#else
+#define CHECK_DBG(condition)
+#define CHECK_EQ_DBG(x,y)
+#define CHECK_NE_DBG(x,y)
+#define CHECK_LE_DBG(x,y)
+#define CHECK_LT_DBG(x,y)
+#define CHECK_GE_DBG(x,y)
+#define CHECK_GT_DBG(x,y)
+#define TRESPASS_DBG(...)
+#endif
struct ADebug {
enum Level {
diff --git a/media/libstagefright/include/foundation/FileDescriptor.h b/media/libstagefright/include/foundation/FileDescriptor.h
new file mode 100644
index 0000000..7acf4b8
--- /dev/null
+++ b/media/libstagefright/include/foundation/FileDescriptor.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2017 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 STAGEFRIGHT_FOUNDATION_FILE_DESCRIPTOR_H_
+#define STAGEFRIGHT_FOUNDATION_FILE_DESCRIPTOR_H_
+
+#include <memory>
+
+namespace android {
+
+/**
+ * FileDescriptor is a utility class for managing file descriptors in a scoped way.
+ *
+ * usage:
+ *
+ * status_t function(int fd) {
+ * FileDescriptor::Autoclose managedFd(fd);
+ * if (error_condition)
+ * return ERROR;
+ * next_function(managedFd.release());
+ * }
+ */
+struct FileDescriptor {
+ // created this class with minimal methods. more methods can be added here to manage
+ // a shared file descriptor object.
+
+ /**
+ * A locally scoped managed file descriptor object. This object is not shareable/copiable and
+ * is not thread safe.
+ */
+ struct Autoclose {
+ // created this class with minimal methods
+ /**
+ * Creates a locally scoped file descriptor holder object taking ownership of the passed in
+ * file descriptor.
+ */
+ Autoclose(int fd)
+ : mFd(fd) {
+
+ }
+
+ ~Autoclose() {
+ if (isValid()) {
+ ::close(mFd);
+ mFd = kInvalidFileDescriptor;
+ }
+ }
+
+ /**
+ * Releases the managed file descriptor from the holder. This invalidates the (remaining)
+ * file descriptor in this object.
+ */
+ int release() {
+ int managedFd = mFd;
+ mFd = kInvalidFileDescriptor;
+ return managedFd;
+ }
+
+ /**
+ * Checks whether the managed file descriptor is valid
+ */
+ bool isValid() const {
+ return mFd >= 0;
+ }
+
+ private:
+ // not yet needed
+
+ /**
+ * Returns the managed file descriptor from this object without releasing the ownership.
+ * The returned file descriptor has the same lifecycle as the managed file descriptor
+ * in this object. Therefore, care must be taken that it is not closed, and that this
+ * object keeps managing the returned file descriptor for the duration of its use.
+ */
+ int get() const {
+ return mFd;
+ }
+
+ private:
+ int mFd;
+
+ enum {
+ kInvalidFileDescriptor = -1,
+ };
+
+ DISALLOW_EVIL_CONSTRUCTORS(Autoclose);
+ };
+
+private:
+ std::shared_ptr<Autoclose> mSharedFd;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_FOUNDATION_FLAGGED_H_
+
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index afbde6a..5257b50 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -26,6 +26,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/ColorUtils.h>
+#include <media/stagefright/foundation/FileDescriptor.h>
#include <media/hardware/MetadataBufferType.h>
#include <ui/GraphicBuffer.h>
@@ -39,29 +40,236 @@
#include <inttypes.h>
#include "FrameDropper.h"
+#include <functional>
+#include <memory>
+
namespace android {
+/**
+ * A copiable object managing a buffer in the buffer cache managed by the producer. This object
+ * holds a reference to the buffer, and maintains which buffer slot it belongs to (if any), and
+ * whether it is still in a buffer slot. It also maintains whether there are any outstanging acquire
+ * references to it (by buffers acquired from the slot) mainly so that we can keep a debug
+ * count of how many buffers we need to still release back to the producer.
+ */
+struct GraphicBufferSource::CachedBuffer {
+ /**
+ * Token that is used to track acquire counts (as opposed to all references to this object).
+ */
+ struct Acquirable { };
+
+ /**
+ * Create using a buffer cached in a slot.
+ */
+ CachedBuffer(slot_id slot, const sp<GraphicBuffer> &graphicBuffer)
+ : mIsCached(true),
+ mSlot(slot),
+ mGraphicBuffer(graphicBuffer),
+ mAcquirable(std::make_shared<Acquirable>()) {
+ }
+
+ /**
+ * Returns the cache slot that this buffer is cached in, or -1 if it is no longer cached.
+ *
+ * This assumes that -1 slot id is invalid; though, it is just a benign collision used for
+ * debugging. This object explicitly manages whether it is still cached.
+ */
+ slot_id getSlot() const {
+ return mIsCached ? mSlot : -1;
+ }
+
+ /**
+ * Returns the cached buffer.
+ */
+ sp<GraphicBuffer> getGraphicBuffer() const {
+ return mGraphicBuffer;
+ }
+
+ /**
+ * Checks whether this buffer is still in the buffer cache.
+ */
+ bool isCached() const {
+ return mIsCached;
+ }
+
+ /**
+ * Checks whether this buffer has an acquired reference.
+ */
+ bool isAcquired() const {
+ return mAcquirable.use_count() > 1;
+ }
+
+ /**
+ * Gets and returns a shared acquired reference.
+ */
+ std::shared_ptr<Acquirable> getAcquirable() {
+ return mAcquirable;
+ }
+
+private:
+ friend void GraphicBufferSource::discardBufferAtSlotIndex_l(ssize_t);
+
+ /**
+ * This method to be called when the buffer is no longer in the buffer cache.
+ * Called from discardBufferAtSlotIndex_l.
+ */
+ void onDroppedFromCache() {
+ CHECK_DBG(mIsCached);
+ mIsCached = false;
+ }
+
+ bool mIsCached;
+ slot_id mSlot;
+ sp<GraphicBuffer> mGraphicBuffer;
+ std::shared_ptr<Acquirable> mAcquirable;
+};
+
+/**
+ * A copiable object managing a buffer acquired from the producer. This must always be a cached
+ * buffer. This objects also manages its acquire fence and any release fences that may be returned
+ * by the encoder for this buffer (this buffer may be queued to the encoder multiple times).
+ * If no release fences are added by the encoder, the acquire fence is returned as the release
+ * fence for this - as it is assumed that noone waited for the acquire fence. Otherwise, it is
+ * assumed that the encoder has waited for the acquire fence (or returned it as the release
+ * fence).
+ */
+struct GraphicBufferSource::AcquiredBuffer {
+ AcquiredBuffer(
+ const std::shared_ptr<CachedBuffer> &buffer,
+ std::function<void(AcquiredBuffer *)> onReleased,
+ const sp<Fence> &acquireFence)
+ : mBuffer(buffer),
+ mAcquirable(buffer->getAcquirable()),
+ mAcquireFence(acquireFence),
+ mGotReleaseFences(false),
+ mOnReleased(onReleased) {
+ }
+
+ /**
+ * Adds a release fence returned by the encoder to this object. If this is called with an
+ * valid file descriptor, it is added to the list of release fences. These are returned to the
+ * producer on release() as a merged fence. Regardless of the validity of the file descriptor,
+ * we take note that a release fence was attempted to be added and the acquire fence can now be
+ * assumed as acquired.
+ */
+ void addReleaseFenceFd(int fenceFd) {
+ // save all release fences - these will be propagated to the producer if this buffer is
+ // ever released to it
+ if (fenceFd >= 0) {
+ mReleaseFenceFds.push_back(fenceFd);
+ }
+ mGotReleaseFences = true;
+ }
+
+ /**
+ * Returns the acquire fence file descriptor associated with this object.
+ */
+ int getAcquireFenceFd() {
+ if (mAcquireFence == nullptr || !mAcquireFence->isValid()) {
+ return -1;
+ }
+ return mAcquireFence->dup();
+ }
+
+ /**
+ * Returns whether the buffer is still in the buffer cache.
+ */
+ bool isCached() const {
+ return mBuffer->isCached();
+ }
+
+ /**
+ * Returns the acquired buffer.
+ */
+ sp<GraphicBuffer> getGraphicBuffer() const {
+ return mBuffer->getGraphicBuffer();
+ }
+
+ /**
+ * Returns the slot that this buffer is cached at, or -1 otherwise.
+ *
+ * This assumes that -1 slot id is invalid; though, it is just a benign collision used for
+ * debugging. This object explicitly manages whether it is still cached.
+ */
+ slot_id getSlot() const {
+ return mBuffer->getSlot();
+ }
+
+ /**
+ * Creates and returns a release fence object from the acquire fence and/or any release fences
+ * added. If no release fences were added (even if invalid), returns the acquire fence.
+ * Otherwise, it returns a merged fence from all the valid release fences added.
+ */
+ sp<Fence> getReleaseFence() {
+ // If did not receive release fences, we assume this buffer was not consumed (it was
+ // discarded or dropped). In this case release the acquire fence as the release fence.
+ // We do this here to avoid a dup, close and recreation of the Fence object.
+ if (!mGotReleaseFences) {
+ return mAcquireFence;
+ }
+ sp<Fence> ret = getReleaseFence(0, mReleaseFenceFds.size());
+ // clear fds as fence took ownership of them
+ mReleaseFenceFds.clear();
+ return ret;
+ }
+
+ // this video buffer is no longer referenced by the codec (or kept for later encoding)
+ // it is now safe to release to the producer
+ ~AcquiredBuffer() {
+ //mAcquirable.clear();
+ mOnReleased(this);
+ // mOnRelease method should call getReleaseFence() that releases all fds but just in case
+ ALOGW_IF(!mReleaseFenceFds.empty(), "release fences were not obtained, closing fds");
+ for (int fildes : mReleaseFenceFds) {
+ ::close(fildes);
+ TRESPASS_DBG();
+ }
+ }
+
+private:
+ std::shared_ptr<GraphicBufferSource::CachedBuffer> mBuffer;
+ std::shared_ptr<GraphicBufferSource::CachedBuffer::Acquirable> mAcquirable;
+ sp<Fence> mAcquireFence;
+ Vector<int> mReleaseFenceFds;
+ bool mGotReleaseFences;
+ std::function<void(AcquiredBuffer *)> mOnReleased;
+
+ /**
+ * Creates and returns a release fence from 0 or more release fence file descriptors in from
+ * the specified range in the array.
+ *
+ * @param start start index
+ * @param num number of release fds to merge
+ */
+ sp<Fence> getReleaseFence(size_t start, size_t num) const {
+ if (num == 0) {
+ return Fence::NO_FENCE;
+ } else if (num == 1) {
+ return new Fence(mReleaseFenceFds[start]);
+ } else {
+ return Fence::merge("GBS::AB",
+ getReleaseFence(start, num >> 1),
+ getReleaseFence(start + (num >> 1), num - (num >> 1)));
+ }
+ }
+};
+
GraphicBufferSource::GraphicBufferSource() :
mInitCheck(UNKNOWN_ERROR),
+ mNumAvailableUnacquiredBuffers(0),
+ mNumOutstandingAcquires(0),
+ mEndOfStream(false),
+ mEndOfStreamSent(false),
+ mLastDataspace(HAL_DATASPACE_UNKNOWN),
mExecuting(false),
mSuspended(false),
mStopTimeUs(-1),
- mLastDataSpace(HAL_DATASPACE_UNKNOWN),
- mNumFramesAvailable(0),
- mNumBufferAcquired(0),
- mEndOfStream(false),
- mEndOfStreamSent(false),
mLastActionTimeUs(-1ll),
- mPrevOriginalTimeUs(-1ll),
mSkipFramesBeforeNs(-1ll),
- mRepeatAfterUs(-1ll),
+ mFrameRepeatIntervalUs(-1ll),
mRepeatLastFrameGeneration(0),
- mRepeatLastFrameTimestamp(-1ll),
- mRepeatLastFrameCount(0),
- mLatestBufferId(-1),
- mLatestBufferFrameNum(0),
- mLatestBufferFence(Fence::NO_FENCE),
- mRepeatBufferDeferred(false),
+ mOutstandingFrameRepeatCount(0),
+ mFrameRepeatBlockedOnCodecBuffer(false),
mTimePerCaptureUs(-1ll),
mTimePerFrameUs(-1ll),
mPrevCaptureUs(-1ll),
@@ -90,18 +298,25 @@
return;
}
- memset(&mColorAspectsPacked, 0, sizeof(mColorAspectsPacked));
+ memset(&mDefaultColorAspectsPacked, 0, sizeof(mDefaultColorAspectsPacked));
CHECK(mInitCheck == NO_ERROR);
}
GraphicBufferSource::~GraphicBufferSource() {
ALOGV("~GraphicBufferSource");
- if (mLatestBufferId >= 0) {
- releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, mLatestBufferFence);
+ {
+ // all acquired buffers must be freed with the mutex locked otherwise our debug assertion
+ // may trigger
+ Mutex::Autolock autoLock(mMutex);
+ mAvailableBuffers.clear();
+ mSubmittedCodecBuffers.clear();
+ mLatestBuffer.mBuffer.reset();
}
- if (mNumBufferAcquired != 0) {
- ALOGW("potential buffer leak (acquired %d)", mNumBufferAcquired);
+
+ if (mNumOutstandingAcquires != 0) {
+ ALOGW("potential buffer leak: acquired=%d", mNumOutstandingAcquires);
+ TRESPASS_DBG();
}
if (mConsumer != NULL) {
status_t err = mConsumer->consumerDisconnect();
@@ -113,11 +328,11 @@
Status GraphicBufferSource::onOmxExecuting() {
Mutex::Autolock autoLock(mMutex);
- ALOGV("--> executing; avail=%zu, codec vec size=%zd",
- mNumFramesAvailable, mCodecBuffers.size());
+ ALOGV("--> executing; available=%zu, submittable=%zd",
+ mAvailableBuffers.size(), mFreeCodecBuffers.size());
CHECK(!mExecuting);
mExecuting = true;
- mLastDataSpace = HAL_DATASPACE_UNKNOWN;
+ mLastDataspace = HAL_DATASPACE_UNKNOWN;
ALOGV("clearing last dataSpace");
// Start by loading up as many buffers as possible. We want to do this,
@@ -129,35 +344,32 @@
// one codec buffer simultaneously. (We could instead try to submit
// all BQ buffers whenever any codec buffer is freed, but if we get the
// initial conditions right that will never be useful.)
- while (mNumFramesAvailable) {
+ while (haveAvailableBuffers_l()) {
if (!fillCodecBuffer_l()) {
- ALOGV("stop load with frames available (codecAvail=%d)",
- isCodecBufferAvailable_l());
+ ALOGV("stop load with available=%zu+%d",
+ mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
break;
}
}
- ALOGV("done loading initial frames, avail=%zu", mNumFramesAvailable);
+ ALOGV("done loading initial frames, available=%zu+%d",
+ mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
// If EOS has already been signaled, and there are no more frames to
// submit, try to send EOS now as well.
- if (mStopTimeUs == -1 && mEndOfStream && mNumFramesAvailable == 0) {
+ if (mStopTimeUs == -1 && mEndOfStream && !haveAvailableBuffers_l()) {
submitEndOfInputStream_l();
}
- if (mRepeatAfterUs > 0ll && mLooper == NULL) {
+ if (mFrameRepeatIntervalUs > 0ll && mLooper == NULL) {
mReflector = new AHandlerReflector<GraphicBufferSource>(this);
mLooper = new ALooper;
mLooper->registerHandler(mReflector);
mLooper->start();
- if (mLatestBufferId >= 0) {
- sp<AMessage> msg =
- new AMessage(kWhatRepeatLastFrame, mReflector);
-
- msg->setInt32("generation", ++mRepeatLastFrameGeneration);
- msg->post(mRepeatAfterUs);
+ if (mLatestBuffer.mBuffer != nullptr) {
+ queueFrameRepeat_l();
}
}
@@ -179,11 +391,6 @@
Status GraphicBufferSource::onOmxLoaded(){
Mutex::Autolock autoLock(mMutex);
- if (!mExecuting) {
- // This can happen if something failed very early.
- ALOGW("Dropped back down to Loaded without Executing");
- }
-
if (mLooper != NULL) {
mLooper->unregisterHandler(mReflector->id());
mReflector.clear();
@@ -192,37 +399,21 @@
mLooper.clear();
}
- ALOGV("--> loaded; avail=%zu eos=%d eosSent=%d acquired=%d",
- mNumFramesAvailable, mEndOfStream, mEndOfStreamSent, mNumBufferAcquired);
+ ALOGV("--> loaded; available=%zu+%d eos=%d eosSent=%d acquired=%d",
+ mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers,
+ mEndOfStream, mEndOfStreamSent, mNumOutstandingAcquires);
// Codec is no longer executing. Releasing all buffers to bq.
- for (int i = (int)mCodecBuffers.size() - 1; i >= 0; --i) {
- if (mCodecBuffers[i].mGraphicBuffer != NULL) {
- int id = mCodecBuffers[i].mSlot;
- if (id != mLatestBufferId) {
- ALOGV("releasing buffer for codec: slot=%d, useCount=%d, latest=%d",
- id, mBufferUseCount[id], mLatestBufferId);
- sp<Fence> fence = new Fence(-1);
- releaseBuffer(id, mCodecBuffers[i].mFrameNumber, fence);
- mBufferUseCount[id] = 0;
- }
- }
- }
- // Also release the latest buffer
- if (mLatestBufferId >= 0) {
- releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, mLatestBufferFence);
- mBufferUseCount[mLatestBufferId] = 0;
- mLatestBufferId = -1;
- }
-
- mCodecBuffers.clear();
+ mFreeCodecBuffers.clear();
+ mSubmittedCodecBuffers.clear();
+ mLatestBuffer.mBuffer.reset();
mOMXNode.clear();
mExecuting = false;
return Status::ok();
}
-Status GraphicBufferSource::onInputBufferAdded(int32_t bufferID) {
+Status GraphicBufferSource::onInputBufferAdded(codec_buffer_id bufferId) {
Mutex::Autolock autoLock(mMutex);
if (mExecuting) {
@@ -232,145 +423,115 @@
return Status::fromServiceSpecificError(INVALID_OPERATION);
}
- ALOGV("addCodecBuffer: bufferID=%u", bufferID);
+ ALOGV("addCodecBuffer: bufferId=%u", bufferId);
- CodecBuffer codecBuffer;
- codecBuffer.mBufferID = bufferID;
- mCodecBuffers.add(codecBuffer);
+ mFreeCodecBuffers.push_back(bufferId);
return Status::ok();
}
-Status GraphicBufferSource::onInputBufferEmptied(
- int32_t bufferID, int fenceFd) {
+Status GraphicBufferSource::onInputBufferEmptied(codec_buffer_id bufferId, int fenceFd) {
Mutex::Autolock autoLock(mMutex);
- if (!mExecuting) {
- if (fenceFd >= 0) {
- ::close(fenceFd);
- }
- return Status::fromServiceSpecificError(INVALID_OPERATION);
- }
+ FileDescriptor::Autoclose fence(fenceFd);
- int cbi = findMatchingCodecBuffer_l(bufferID);
+ ssize_t cbi = mSubmittedCodecBuffers.indexOfKey(bufferId);
if (cbi < 0) {
// This should never happen.
- ALOGE("codecBufferEmptied: buffer not recognized (bufferID=%u)", bufferID);
- if (fenceFd >= 0) {
- ::close(fenceFd);
- }
+ ALOGE("onInputBufferEmptied: buffer not recognized (bufferId=%u)", bufferId);
return Status::fromServiceSpecificError(BAD_VALUE);
}
- ALOGV("codecBufferEmptied: bufferID=%u, cbi=%d", bufferID, cbi);
- CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
+ std::shared_ptr<AcquiredBuffer> buffer = mSubmittedCodecBuffers.valueAt(cbi);
+
+ // Move buffer to available buffers
+ mSubmittedCodecBuffers.removeItemsAt(cbi);
+ mFreeCodecBuffers.push_back(bufferId);
// header->nFilledLen may not be the original value, so we can't compare
// that to zero to see of this was the EOS buffer. Instead we just
- // see if the GraphicBuffer reference was null, which should only ever
- // happen for EOS.
- if (codecBuffer.mGraphicBuffer == NULL) {
+ // see if there is a null AcquiredBuffer, which should only ever happen for EOS.
+ if (buffer == nullptr) {
if (!(mEndOfStream && mEndOfStreamSent)) {
- // This can happen when broken code sends us the same buffer
- // twice in a row.
- ALOGE("ERROR: codecBufferEmptied on non-EOS null buffer "
- "(buffer emptied twice?)");
+ // This can happen when broken code sends us the same buffer twice in a row.
+ ALOGE("onInputBufferEmptied: non-EOS null buffer (bufferId=%u)", bufferId);
+ } else {
+ ALOGV("onInputBufferEmptied: EOS null buffer (bufferId=%u@%zd)", bufferId, cbi);
}
- // No GraphicBuffer to deal with, no additional input or output is
- // expected, so just return.
- if (fenceFd >= 0) {
- ::close(fenceFd);
- }
+ // No GraphicBuffer to deal with, no additional input or output is expected, so just return.
return Status::fromServiceSpecificError(BAD_VALUE);
}
- // Find matching entry in our cached copy of the BufferQueue slots.
- // If we find a match, release that slot. If we don't, the BufferQueue
- // has dropped that GraphicBuffer, and there's nothing for us to release.
- int id = codecBuffer.mSlot;
- sp<Fence> fence = new Fence(fenceFd);
- if (mBufferSlot[id] != NULL &&
- mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
- mBufferUseCount[id]--;
-
- if (mBufferUseCount[id] < 0) {
- ALOGW("mBufferUseCount for bq slot %d < 0 (=%d)", id, mBufferUseCount[id]);
- mBufferUseCount[id] = 0;
- }
- if (id != mLatestBufferId && mBufferUseCount[id] == 0) {
- releaseBuffer(id, codecBuffer.mFrameNumber, fence);
- }
- ALOGV("codecBufferEmptied: slot=%d, cbi=%d, useCount=%d, acquired=%d, handle=%p",
- id, cbi, mBufferUseCount[id], mNumBufferAcquired, mBufferSlot[id]->handle);
- } else {
- ALOGV("codecBufferEmptied: no match for emptied buffer, "
- "slot=%d, cbi=%d, useCount=%d, acquired=%d",
- id, cbi, mBufferUseCount[id], mNumBufferAcquired);
- // we will not reuse codec buffer, so there is no need to wait for fence
+ if (!mExecuting) {
+ // this is fine since this could happen when going from Idle to Loaded
+ ALOGV("onInputBufferEmptied: no longer executing (bufferId=%u@%zd)", bufferId, cbi);
+ return Status::fromServiceSpecificError(OK);
}
- // Mark the codec buffer as available by clearing the GraphicBuffer ref.
- codecBuffer.mGraphicBuffer = NULL;
+ ALOGV("onInputBufferEmptied: bufferId=%d@%zd [slot=%d, useCount=%ld, handle=%p] acquired=%d",
+ bufferId, cbi, buffer->getSlot(), buffer.use_count(), buffer->getGraphicBuffer()->handle,
+ mNumOutstandingAcquires);
- if (mNumFramesAvailable) {
+ buffer->addReleaseFenceFd(fence.release());
+ // release codec reference for video buffer just in case remove does not it
+ buffer.reset();
+
+ if (haveAvailableBuffers_l()) {
// Fill this codec buffer.
CHECK(!mEndOfStreamSent);
- ALOGV("buffer freed, %zu frames avail (eos=%d)",
- mNumFramesAvailable, mEndOfStream);
+ ALOGV("onInputBufferEmptied: buffer freed, feeding codec (available=%zu+%d, eos=%d)",
+ mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
fillCodecBuffer_l();
} else if (mEndOfStream && mStopTimeUs == -1) {
// No frames available, but EOS is pending and no stop time, so use this buffer to
// send that.
- ALOGV("buffer freed, EOS pending");
+ ALOGV("onInputBufferEmptied: buffer freed, submitting EOS");
submitEndOfInputStream_l();
- } else if (mRepeatBufferDeferred) {
+ } else if (mFrameRepeatBlockedOnCodecBuffer) {
bool success = repeatLatestBuffer_l();
- if (success) {
- ALOGV("deferred repeatLatestBuffer_l SUCCESS");
- } else {
- ALOGV("deferred repeatLatestBuffer_l FAILURE");
- }
- mRepeatBufferDeferred = false;
+ ALOGV("onInputBufferEmptied: completing deferred repeatLatestBuffer_l %s",
+ success ? "SUCCESS" : "FAILURE");
+ mFrameRepeatBlockedOnCodecBuffer = false;
}
+ // releaseReleasableBuffers_l();
return Status::ok();
}
-void GraphicBufferSource::onDataSpaceChanged_l(
- android_dataspace dataSpace, android_pixel_format pixelFormat) {
- ALOGD("got buffer with new dataSpace #%x", dataSpace);
- mLastDataSpace = dataSpace;
+void GraphicBufferSource::onDataspaceChanged_l(
+ android_dataspace dataspace, android_pixel_format pixelFormat) {
+ ALOGD("got buffer with new dataSpace #%x", dataspace);
+ mLastDataspace = dataspace;
- if (ColorUtils::convertDataSpaceToV0(dataSpace)) {
- mOMXNode->dispatchDataSpaceChanged(mLastDataSpace, mColorAspectsPacked, pixelFormat);
+ if (ColorUtils::convertDataSpaceToV0(dataspace)) {
+ mOMXNode->dispatchDataSpaceChanged(mLastDataspace, mDefaultColorAspectsPacked, pixelFormat);
}
}
bool GraphicBufferSource::fillCodecBuffer_l() {
- CHECK(mExecuting && mNumFramesAvailable > 0);
+ CHECK(mExecuting && haveAvailableBuffers_l());
- if (mSuspended && mActionQueue.empty()) {
- return false;
- }
-
- int cbi = findAvailableCodecBuffer_l();
- if (cbi < 0) {
+ if (mFreeCodecBuffers.empty()) {
// No buffers available, bail.
- ALOGV("fillCodecBuffer_l: no codec buffers, avail now %zu",
- mNumFramesAvailable);
+ ALOGV("fillCodecBuffer_l: no codec buffers, available=%zu+%d",
+ mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
return false;
}
- ALOGV("fillCodecBuffer_l: acquiring buffer, avail=%zu",
- mNumFramesAvailable);
- BufferItem item;
- status_t err = acquireBuffer(&item);
- if (err != OK) {
- ALOGE("fillCodecBuffer_l: acquireBuffer returned err=%d", err);
- return false;
+ VideoBuffer item;
+ if (mAvailableBuffers.empty()) {
+ ALOGV("fillCodecBuffer_l: acquiring available buffer, available=%zu+%d",
+ mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
+ if (acquireBuffer_l(&item) != OK) {
+ ALOGE("fillCodecBuffer_l: failed to acquire available buffer");
+ return false;
+ }
+ } else {
+ ALOGV("fillCodecBuffer_l: getting available buffer, available=%zu+%d",
+ mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
+ item = *mAvailableBuffers.begin();
+ mAvailableBuffers.erase(mAvailableBuffers.begin());
}
- int64_t itemTimeUs = item.mTimestamp / 1000;
-
- mNumFramesAvailable--;
+ int64_t itemTimeUs = item.mTimestampNs / 1000;
// Process ActionItem in the Queue if there is any. If a buffer's timestamp
// is smaller than the first action's timestamp, no action need to be performed.
@@ -382,7 +543,6 @@
// [pause 1us], [resume 2us], [pause 3us], [resume 4us], [pause 5us].... Upon
// receiving a buffer with timestamp 3.5us, only the action [pause, 3us] needs
// to be handled and [pause, 1us], [resume 2us] will be discarded.
- bool dropped = false;
bool done = false;
bool seeStopAction = false;
if (!mActionQueue.empty()) {
@@ -394,7 +554,6 @@
// All the actions are ahead. No action need to perform now.
// Release the buffer if is in suspended state, or process the buffer
// if not in suspended state.
- dropped = mSuspended;
done = true;
}
@@ -402,7 +561,8 @@
// Find the newest action that with timestamp smaller than itemTimeUs. Then
// remove all the actions before and include the newest action.
List<ActionItem>::iterator it = mActionQueue.begin();
- while (it != mActionQueue.end() && it->mActionTimeUs <= itemTimeUs) {
+ while (it != mActionQueue.end() && it->mActionTimeUs <= itemTimeUs
+ && nextAction.mAction != ActionItem::STOP) {
nextAction = *it;
++it;
}
@@ -413,7 +573,6 @@
case ActionItem::PAUSE:
{
mSuspended = true;
- dropped = true;
ALOGV("RUNNING/PAUSE -> PAUSE at buffer %lld us PAUSE Time: %lld us",
(long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
break;
@@ -429,167 +588,129 @@
{
ALOGV("RUNNING/PAUSE -> STOP at buffer %lld us STOP Time: %lld us",
(long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
- dropped = true;
// Clear the whole ActionQueue as recording is done
mActionQueue.clear();
seeStopAction = true;
break;
}
default:
- ALOGE("Unknown action type");
+ TRESPASS_DBG("Unknown action type");
+ // return true here because we did consume an available buffer, so the
+ // loop in onOmxExecuting will eventually terminate even if we hit this.
return false;
}
}
}
- if (dropped) {
- releaseBuffer(item.mSlot, item.mFrameNumber, item.mFence);
- if (seeStopAction) {
- // Clear all the buffers before setting mEndOfStream and signal EndOfInputStream.
- if (!releaseAllBuffers()) {
- ALOGW("Failed to release all the buffers when handling STOP action");
- }
- mEndOfStream = true;
- submitEndOfInputStream_l();
- }
+ if (seeStopAction) {
+ // Clear all the buffers before setting mEndOfStream and signal EndOfInputStream.
+ releaseAllAvailableBuffers_l();
+ mEndOfStream = true;
+ submitEndOfInputStream_l();
return true;
}
- if (item.mDataSpace != mLastDataSpace) {
- onDataSpaceChanged_l(
- item.mDataSpace, (android_pixel_format)mBufferSlot[item.mSlot]->getPixelFormat());
+ if (mSuspended) {
+ return true;
}
- err = UNKNOWN_ERROR;
+ int err = UNKNOWN_ERROR;
// only submit sample if start time is unspecified, or sample
// is queued after the specified start time
- if (mSkipFramesBeforeNs < 0ll || item.mTimestamp >= mSkipFramesBeforeNs) {
+ if (mSkipFramesBeforeNs < 0ll || item.mTimestampNs >= mSkipFramesBeforeNs) {
// if start time is set, offset time stamp by start time
if (mSkipFramesBeforeNs > 0) {
- item.mTimestamp -= mSkipFramesBeforeNs;
+ item.mTimestampNs -= mSkipFramesBeforeNs;
}
- int64_t timeUs = item.mTimestamp / 1000;
+ int64_t timeUs = item.mTimestampNs / 1000;
if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) {
ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs));
// set err to OK so that the skipped frame can still be saved as the lastest frame
err = OK;
- dropped = true;
} else {
- err = submitBuffer_l(item, cbi);
+ err = submitBuffer_l(item); // this takes shared ownership of the acquired buffer on succeess
}
}
if (err != OK) {
- ALOGV("submitBuffer_l failed, releasing bq slot %d", item.mSlot);
- releaseBuffer(item.mSlot, item.mFrameNumber, item.mFence);
+ ALOGV("submitBuffer_l failed, will release bq slot %d", item.mBuffer->getSlot());
+ return true;
} else {
// Don't set the last buffer id if we're not repeating,
// we'll be holding on to the last buffer for nothing.
- if (mRepeatAfterUs > 0ll) {
+ if (mFrameRepeatIntervalUs > 0ll) {
setLatestBuffer_l(item);
}
- if (!dropped) {
- ++mBufferUseCount[item.mSlot];
- }
- ALOGV("buffer submitted: slot=%d, cbi=%d, useCount=%d, acquired=%d",
- item.mSlot, cbi, mBufferUseCount[item.mSlot], mNumBufferAcquired);
+ ALOGV("buffer submitted [slot=%d, useCount=%ld] acquired=%d",
+ item.mBuffer->getSlot(), item.mBuffer.use_count(), mNumOutstandingAcquires);
}
return true;
}
bool GraphicBufferSource::repeatLatestBuffer_l() {
- CHECK(mExecuting && mNumFramesAvailable == 0);
+ CHECK(mExecuting && !haveAvailableBuffers_l());
- if (mLatestBufferId < 0 || mSuspended) {
- return false;
- }
- if (mBufferSlot[mLatestBufferId] == NULL) {
- // This can happen if the remote side disconnects, causing
- // onBuffersReleased() to NULL out our copy of the slots. The
- // buffer is gone, so we have nothing to show.
- //
- // To be on the safe side we try to release the buffer.
- ALOGD("repeatLatestBuffer_l: slot was NULL");
- mConsumer->releaseBuffer(
- mLatestBufferId,
- mLatestBufferFrameNum,
- EGL_NO_DISPLAY,
- EGL_NO_SYNC_KHR,
- mLatestBufferFence);
- mLatestBufferId = -1;
- mLatestBufferFrameNum = 0;
- mLatestBufferFence = Fence::NO_FENCE;
+ if (mLatestBuffer.mBuffer == nullptr || mSuspended) {
return false;
}
- int cbi = findAvailableCodecBuffer_l();
- if (cbi < 0) {
+ if (mFreeCodecBuffers.empty()) {
// No buffers available, bail.
ALOGV("repeatLatestBuffer_l: no codec buffers.");
return false;
}
- BufferItem item;
- item.mSlot = mLatestBufferId;
- item.mFrameNumber = mLatestBufferFrameNum;
- item.mTimestamp = mRepeatLastFrameTimestamp;
- item.mFence = mLatestBufferFence;
+ if (!mLatestBuffer.mBuffer->isCached()) {
+ ALOGV("repeatLatestBuffer_l: slot was discarded, but repeating our own reference");
+ }
- status_t err = submitBuffer_l(item, cbi);
-
+ // it is ok to update the timestamp of latest buffer as it is only used for submission
+ status_t err = submitBuffer_l(mLatestBuffer);
if (err != OK) {
return false;
}
- ++mBufferUseCount[item.mSlot];
-
/* repeat last frame up to kRepeatLastFrameCount times.
* in case of static scene, a single repeat might not get rid of encoder
* ghosting completely, refresh a couple more times to get better quality
*/
- if (--mRepeatLastFrameCount > 0) {
- mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
-
- if (mReflector != NULL) {
- sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
- msg->setInt32("generation", ++mRepeatLastFrameGeneration);
- msg->post(mRepeatAfterUs);
- }
+ if (--mOutstandingFrameRepeatCount > 0) {
+ // set up timestamp for repeat frame
+ mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
+ queueFrameRepeat_l();
}
return true;
}
-void GraphicBufferSource::setLatestBuffer_l(const BufferItem &item) {
- if (mLatestBufferId >= 0 && mBufferUseCount[mLatestBufferId] == 0) {
- releaseBuffer(mLatestBufferId, mLatestBufferFrameNum, mLatestBufferFence);
- // mLatestBufferFence will be set to new fence just below
- }
+void GraphicBufferSource::setLatestBuffer_l(const VideoBuffer &item) {
+ mLatestBuffer = item;
- mLatestBufferId = item.mSlot;
- mLatestBufferFrameNum = item.mFrameNumber;
- mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
+ ALOGV("setLatestBuffer_l: [slot=%d, useCount=%ld]",
+ mLatestBuffer.mBuffer->getSlot(), mLatestBuffer.mBuffer.use_count());
- ALOGV("setLatestBuffer_l: slot=%d, useCount=%d",
- item.mSlot, mBufferUseCount[item.mSlot]);
+ mOutstandingFrameRepeatCount = kRepeatLastFrameCount;
+ // set up timestamp for repeat frame
+ mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
+ queueFrameRepeat_l();
+}
- mRepeatBufferDeferred = false;
- mRepeatLastFrameCount = kRepeatLastFrameCount;
- mLatestBufferFence = item.mFence;
+void GraphicBufferSource::queueFrameRepeat_l() {
+ mFrameRepeatBlockedOnCodecBuffer = false;
if (mReflector != NULL) {
sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
msg->setInt32("generation", ++mRepeatLastFrameGeneration);
- msg->post(mRepeatAfterUs);
+ msg->post(mFrameRepeatIntervalUs);
}
}
-bool GraphicBufferSource::getTimestamp(
- const BufferItem &item, int64_t *codecTimeUs) {
- int64_t timeUs = item.mTimestamp / 1000;
+bool GraphicBufferSource::calculateCodecTimestamp_l(
+ nsecs_t bufferTimeNs, int64_t *codecTimeUs) {
+ int64_t timeUs = bufferTimeNs / 1000;
timeUs += mInputBufferTimeOffsetUs;
if (mTimePerCaptureUs > 0ll
@@ -610,7 +731,7 @@
ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
return false;
}
- mPrevCaptureUs = mPrevCaptureUs + nFrames * mTimePerCaptureUs;
+ mPrevCaptureUs += mTimePerCaptureUs * nFrames;
mPrevFrameUs += mTimePerFrameUs * nFrames;
}
@@ -618,53 +739,58 @@
static_cast<long long>(timeUs),
static_cast<long long>(mPrevCaptureUs),
static_cast<long long>(mPrevFrameUs));
-
- *codecTimeUs = mPrevFrameUs;
- return true;
} else {
- int64_t originalTimeUs = timeUs;
- if (originalTimeUs <= mPrevOriginalTimeUs) {
- // Drop the frame if it's going backward in time. Bad timestamp
- // could disrupt encoder's rate control completely.
+ if (timeUs <= mPrevFrameUs) {
+ // Drop the frame if it's going backward in time. Bad timestamp
+ // could disrupt encoder's rate control completely.
ALOGW("Dropping frame that's going backward in time");
return false;
}
- mPrevOriginalTimeUs = originalTimeUs;
+ mPrevFrameUs = timeUs;
}
- *codecTimeUs = timeUs;
+ *codecTimeUs = mPrevFrameUs;
return true;
}
-status_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) {
- ALOGV("submitBuffer_l: slot=%d, cbi=%d", item.mSlot, cbi);
+status_t GraphicBufferSource::submitBuffer_l(const VideoBuffer &item) {
+ CHECK(!mFreeCodecBuffers.empty());
+ IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
+ mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
+
+ ALOGV("submitBuffer_l [slot=%d, bufferId=%d]", item.mBuffer->getSlot(), codecBufferId);
int64_t codecTimeUs;
- if (!getTimestamp(item, &codecTimeUs)) {
+ if (!calculateCodecTimestamp_l(item.mTimestampNs, &codecTimeUs)) {
return UNKNOWN_ERROR;
}
- CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
- codecBuffer.mGraphicBuffer = mBufferSlot[item.mSlot];
- codecBuffer.mSlot = item.mSlot;
- codecBuffer.mFrameNumber = item.mFrameNumber;
+ if ((android_dataspace)item.mDataspace != mLastDataspace) {
+ onDataspaceChanged_l(
+ item.mDataspace,
+ (android_pixel_format)item.mBuffer->getGraphicBuffer()->format);
+ }
- IOMX::buffer_id bufferID = codecBuffer.mBufferID;
- const sp<GraphicBuffer> &buffer = codecBuffer.mGraphicBuffer;
- int fenceID = item.mFence->isValid() ? item.mFence->dup() : -1;
-
+ std::shared_ptr<AcquiredBuffer> buffer = item.mBuffer;
+ // use a GraphicBuffer for now as OMXNodeInstance is using GraphicBuffers to hold references
+ // and it requires this graphic buffer to be able to hold its reference
+ // and thus we would need to create a new GraphicBuffer from an ANWBuffer separate from the
+ // acquired GraphicBuffer.
+ // TODO: this can be reworked globally to use ANWBuffer references
+ sp<GraphicBuffer> graphicBuffer = buffer->getGraphicBuffer();
status_t err = mOMXNode->emptyBuffer(
- bufferID, OMX_BUFFERFLAG_ENDOFFRAME, buffer, codecTimeUs, fenceID);
+ codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME, graphicBuffer, codecTimeUs,
+ buffer->getAcquireFenceFd());
if (err != OK) {
ALOGW("WARNING: emptyGraphicBuffer failed: 0x%x", err);
- codecBuffer.mGraphicBuffer = NULL;
return err;
}
- ALOGV("emptyGraphicBuffer succeeded, bufferID=%u buf=%p bufhandle=%p",
- bufferID, buffer->getNativeBuffer(), buffer->handle);
+ ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, buffer);
+ ALOGV("emptyGraphicBuffer succeeded, bufferId=%u@%zd bufhandle=%p",
+ codecBufferId, cbix, graphicBuffer->handle);
return OK;
}
@@ -675,119 +801,136 @@
return;
}
- int cbi = findAvailableCodecBuffer_l();
- if (cbi < 0) {
+ if (mFreeCodecBuffers.empty()) {
ALOGV("submitEndOfInputStream_l: no codec buffers available");
return;
}
+ IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
+ mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
- // We reject any additional incoming graphic buffers, so there's no need
- // to stick a placeholder into codecBuffer.mGraphicBuffer to mark it as
- // in-use.
- CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
- IOMX::buffer_id bufferID = codecBuffer.mBufferID;
-
- status_t err = mOMXNode->emptyBuffer(bufferID,
- OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS);
+ // We reject any additional incoming graphic buffers. There is no acquired buffer used for EOS
+ status_t err = mOMXNode->emptyBuffer(
+ codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS);
if (err != OK) {
ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
} else {
- ALOGV("submitEndOfInputStream_l: buffer submitted, bufferID=%u cbi=%d",
- bufferID, cbi);
+ ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, nullptr);
+ ALOGV("submitEndOfInputStream_l: buffer submitted, bufferId=%u@%zd", codecBufferId, cbix);
mEndOfStreamSent = true;
}
}
-int GraphicBufferSource::findAvailableCodecBuffer_l() {
- CHECK(mCodecBuffers.size() > 0);
-
- for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
- if (mCodecBuffers[i].mGraphicBuffer == NULL) {
- return i;
- }
- }
- return -1;
-}
-
-int GraphicBufferSource::findMatchingCodecBuffer_l(IOMX::buffer_id bufferID) {
- for (int i = (int)mCodecBuffers.size() - 1; i>= 0; --i) {
- if (mCodecBuffers[i].mBufferID == bufferID) {
- return i;
- }
- }
- return -1;
-}
-
-status_t GraphicBufferSource::acquireBuffer(BufferItem *bi) {
- status_t err = mConsumer->acquireBuffer(bi, 0);
+status_t GraphicBufferSource::acquireBuffer_l(VideoBuffer *ab) {
+ BufferItem bi;
+ status_t err = mConsumer->acquireBuffer(&bi, 0);
if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
// shouldn't happen
- ALOGW("acquireBuffer: frame was not available");
+ ALOGW("acquireBuffer_l: frame was not available");
return err;
} else if (err != OK) {
- ALOGW("acquireBuffer: failed with err=%d", err);
+ ALOGW("acquireBuffer_l: failed with err=%d", err);
return err;
}
- // If this is the first time we're seeing this buffer, add it to our
- // slot table.
- if (bi->mGraphicBuffer != NULL) {
- ALOGV("acquireBuffer: setting mBufferSlot %d", bi->mSlot);
- mBufferSlot[bi->mSlot] = bi->mGraphicBuffer;
- mBufferUseCount[bi->mSlot] = 0;
+ --mNumAvailableUnacquiredBuffers;
+
+ // Manage our buffer cache.
+ std::shared_ptr<CachedBuffer> buffer;
+ ssize_t bsi = mBufferSlots.indexOfKey(bi.mSlot);
+ if (bi.mGraphicBuffer != NULL) {
+ // replace/initialize slot with new buffer
+ ALOGV("acquireBuffer_l: %s buffer slot %d", bsi < 0 ? "setting" : "UPDATING", bi.mSlot);
+ if (bsi >= 0) {
+ discardBufferAtSlotIndex_l(bsi);
+ } else {
+ bsi = mBufferSlots.add(bi.mSlot, nullptr);
+ }
+ buffer = std::make_shared<CachedBuffer>(bi.mSlot, bi.mGraphicBuffer);
+ mBufferSlots.replaceValueAt(bsi, buffer);
+ } else {
+ buffer = mBufferSlots.valueAt(bsi);
}
- mNumBufferAcquired++;
+ int64_t frameNum = bi.mFrameNumber;
+
+ std::shared_ptr<AcquiredBuffer> acquiredBuffer =
+ std::make_shared<AcquiredBuffer>(
+ buffer,
+ [frameNum, this](AcquiredBuffer *buffer){
+ // AcquiredBuffer's destructor should always be called when mMutex is locked.
+ // If we had a reentrant mutex, we could just lock it again to ensure this.
+ if (mMutex.tryLock() == 0) {
+ TRESPASS_DBG();
+ mMutex.unlock();
+ }
+
+ // we can release buffers immediately if not using adapters
+ // alternately, we could add them to mSlotsToRelease, but we would
+ // somehow need to propagate frame number to that queue
+ if (buffer->isCached()) {
+ --mNumOutstandingAcquires;
+ mConsumer->releaseBuffer(
+ buffer->getSlot(), frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
+ buffer->getReleaseFence());
+ }
+ },
+ bi.mFence);
+ VideoBuffer videoBuffer{acquiredBuffer, bi.mTimestamp, bi.mDataSpace};
+ *ab = videoBuffer;
+ ++mNumOutstandingAcquires;
return OK;
}
-/*
- * Releases an acquired buffer back to the consumer.
- *
- * id: buffer slot to release
- * frameNum: frame number of the frame being released
- * fence: fence of the frame being released
- */
-void GraphicBufferSource::releaseBuffer(
- int id, uint64_t frameNum, const sp<Fence> &fence) {
- ALOGV("releaseBuffer: slot=%d", id);
- mConsumer->releaseBuffer(
- id, frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, fence);
- mNumBufferAcquired--;
-}
-
// BufferQueue::ConsumerListener callback
-void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {
+void GraphicBufferSource::onFrameAvailable(const BufferItem& item __unused) {
Mutex::Autolock autoLock(mMutex);
- ALOGV("onFrameAvailable exec=%d avail=%zu",
- mExecuting, mNumFramesAvailable);
+ ALOGV("onFrameAvailable: executing=%d available=%zu+%d",
+ mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
+ ++mNumAvailableUnacquiredBuffers;
- if (mOMXNode == NULL || mEndOfStreamSent || (mSuspended && mActionQueue.empty())) {
- if (mEndOfStreamSent) {
- // This should only be possible if a new buffer was queued after
- // EOS was signaled, i.e. the app is misbehaving.
+ // For BufferQueue we cannot acquire a buffer if we cannot immediately feed it to the codec
+ // OR we are discarding this buffer (acquiring and immediately releasing it), which makes
+ // this an ugly logic.
+ // NOTE: We could also rely on our debug counter but that is meant only as a debug counter.
+ if (!areWeDiscardingAvailableBuffers_l() && mFreeCodecBuffers.empty()) {
+ // we may not be allowed to acquire a possibly encodable buffer, so just note that
+ // it is available
+ ALOGV("onFrameAvailable: cannot acquire buffer right now, do it later");
- ALOGW("onFrameAvailable: EOS is sent, ignoring frame");
- } else {
- ALOGV("onFrameAvailable: suspended, ignoring frame");
- }
-
- BufferItem item;
- status_t err = acquireBuffer(&item);
- if (err == OK) {
- releaseBuffer(item.mSlot, item.mFrameNumber, item.mFence);
- } else {
- ALOGE("onFrameAvailable: acquireBuffer returned err=%d", err);
- }
- return;
+ ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
}
- mNumFramesAvailable++;
+ VideoBuffer buffer;
+ status_t err = acquireBuffer_l(&buffer);
+ if (err != OK) {
+ ALOGE("onFrameAvailable: acquireBuffer returned err=%d", err);
+ } else {
+ onBufferAcquired_l(buffer);
+ }
+}
- mRepeatBufferDeferred = false;
- ++mRepeatLastFrameGeneration;
+bool GraphicBufferSource::areWeDiscardingAvailableBuffers_l() {
+ return mEndOfStreamSent // already sent EOS to codec
+ || mOMXNode == nullptr // there is no codec connected
+ || (mSuspended && mActionQueue.empty()) // we are suspended and not waiting for
+ // any further action
+ || !mExecuting;
+}
- if (mExecuting) {
- fillCodecBuffer_l();
+void GraphicBufferSource::onBufferAcquired_l(const VideoBuffer &buffer) {
+ if (mEndOfStreamSent) {
+ // This should only be possible if a new buffer was queued after
+ // EOS was signaled, i.e. the app is misbehaving.
+ ALOGW("onFrameAvailable: EOS is sent, ignoring frame");
+ } else if (mOMXNode == NULL || (mSuspended && mActionQueue.empty())) {
+ // FIXME: if we are suspended but have a resume queued we will stop repeating the last
+ // frame. Is that the desired behavior?
+ ALOGV("onFrameAvailable: suspended, ignoring frame");
+ } else {
+ ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
+ mAvailableBuffers.push_back(buffer);
+ if (mExecuting) {
+ fillCodecBuffer_l();
+ }
}
}
@@ -805,25 +948,55 @@
for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
if ((slotMask & 0x01) != 0) {
- // Last buffer (if set) is always acquired even if its use count
- // is 0, because we could have skipped that frame but kept it for
- // repeating. Otherwise a buffer is only acquired if use count>0.
- if (mBufferSlot[i] != NULL &&
- (mBufferUseCount[i] > 0 || mLatestBufferId == i)) {
- ALOGV("releasing acquired buffer: slot=%d, useCount=%d, latest=%d",
- i, mBufferUseCount[i], mLatestBufferId);
- mNumBufferAcquired--;
- }
- if (mLatestBufferId == i) {
- mLatestBufferId = -1;
- }
- mBufferSlot[i] = NULL;
- mBufferUseCount[i] = 0;
+ discardBufferInSlot_l(i);
}
slotMask >>= 1;
}
}
+void GraphicBufferSource::discardBufferInSlot_l(GraphicBufferSource::slot_id i) {
+ ssize_t bsi = mBufferSlots.indexOfKey(i);
+ if (bsi < 0) {
+ ALOGW("releasing an unpopulated slot: %d", i);
+ } else {
+ discardBufferAtSlotIndex_l(bsi);
+ mBufferSlots.removeItemsAt(bsi);
+ }
+}
+
+void GraphicBufferSource::discardBufferAtSlotIndex_l(ssize_t bsi) {
+ const std::shared_ptr<CachedBuffer>& buffer = mBufferSlots.valueAt(bsi);
+ // use -2 if there is no latest buffer, and -1 if it is no longer cached
+ slot_id latestBufferSlot =
+ mLatestBuffer.mBuffer == nullptr ? -2 : mLatestBuffer.mBuffer->getSlot();
+ ALOGV("releasing acquired buffer: [slot=%d, useCount=%ld], latest: [slot=%d]",
+ mBufferSlots.keyAt(bsi), buffer.use_count(), latestBufferSlot);
+ mBufferSlots.valueAt(bsi)->onDroppedFromCache();
+
+ // If the slot of an acquired buffer is discarded, that buffer will not have to be
+ // released to the producer, so account it here. However, it is possible that the
+ // acquired buffer has already been discarded so check if it still is.
+ if (buffer->isAcquired()) {
+ --mNumOutstandingAcquires;
+ }
+
+ // clear the buffer reference (not technically needed as caller either replaces or deletes
+ // it; done here for safety).
+ mBufferSlots.editValueAt(bsi).reset();
+ CHECK_DBG(buffer == nullptr);
+}
+
+void GraphicBufferSource::releaseAllAvailableBuffers_l() {
+ mAvailableBuffers.clear();
+ while (mNumAvailableUnacquiredBuffers > 0) {
+ VideoBuffer item;
+ if (acquireBuffer_l(&item) != OK) {
+ ALOGW("releaseAllAvailableBuffers: failed to acquire available unacquired buffer");
+ break;
+ }
+ }
+}
+
// BufferQueue::ConsumerListener callback
void GraphicBufferSource::onSidebandStreamChanged() {
ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
@@ -867,24 +1040,20 @@
mConsumer->setConsumerUsageBits(consumerUsage);
// Sets the default buffer data space
- ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumBufferAcquired);
+ ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumOutstandingAcquires);
mConsumer->setDefaultBufferDataSpace((android_dataspace)dataSpace);
- mLastDataSpace = (android_dataspace)dataSpace;
+ mLastDataspace = (android_dataspace)dataSpace;
mExecuting = false;
mSuspended = false;
mEndOfStream = false;
mEndOfStreamSent = false;
- mPrevOriginalTimeUs = -1ll;
mSkipFramesBeforeNs = -1ll;
- mRepeatAfterUs = -1ll;
+ mFrameRepeatIntervalUs = -1ll;
mRepeatLastFrameGeneration = 0;
- mRepeatLastFrameTimestamp = -1ll;
- mRepeatLastFrameCount = 0;
- mLatestBufferId = -1;
- mLatestBufferFrameNum = 0;
- mLatestBufferFence = Fence::NO_FENCE;
- mRepeatBufferDeferred = false;
+ mOutstandingFrameRepeatCount = 0;
+ mLatestBuffer.mBuffer.reset();
+ mFrameRepeatBlockedOnCodecBuffer = false;
mTimePerCaptureUs = -1ll;
mTimePerFrameUs = -1ll;
mPrevCaptureUs = -1ll;
@@ -930,20 +1099,15 @@
} else {
if (suspend) {
mSuspended = true;
-
- if (!releaseAllBuffers()) {
- ALOGW("Failed to release all the buffers during suspend");
- }
+ releaseAllAvailableBuffers_l();
return OK;
} else {
-
mSuspended = false;
-
- if (mExecuting && mNumFramesAvailable == 0 && mRepeatBufferDeferred) {
+ if (mExecuting && !haveAvailableBuffers_l()
+ && mFrameRepeatBlockedOnCodecBuffer) {
if (repeatLatestBuffer_l()) {
ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS");
-
- mRepeatBufferDeferred = false;
+ mFrameRepeatBlockedOnCodecBuffer = false;
} else {
ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE");
}
@@ -953,23 +1117,6 @@
return OK;
}
-bool GraphicBufferSource::releaseAllBuffers() {
- while (mNumFramesAvailable > 0) {
- BufferItem item;
- status_t err = acquireBuffer(&item);
-
- if (err != OK) {
- ALOGE("releaseAllBuffers: acquireBuffer fail returned err=%d", err);
- return false;;
- }
-
- --mNumFramesAvailable;
-
- releaseBuffer(item.mSlot, item.mFrameNumber, item.mFence);
- }
- return true;
-}
-
status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
ALOGV("setRepeatPreviousFrameDelayUs: delayUs=%lld", (long long)repeatAfterUs);
@@ -979,7 +1126,7 @@
return INVALID_OPERATION;
}
- mRepeatAfterUs = repeatAfterUs;
+ mFrameRepeatIntervalUs = repeatAfterUs;
return OK;
}
@@ -1073,7 +1220,7 @@
status_t GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
Mutex::Autolock autoLock(mMutex);
- mColorAspectsPacked = aspectsPacked;
+ mDefaultColorAspectsPacked = aspectsPacked;
ColorAspects colorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))",
colorAspects.mRange, asString(colorAspects.mRange),
@@ -1086,8 +1233,8 @@
status_t GraphicBufferSource::signalEndOfInputStream() {
Mutex::Autolock autoLock(mMutex);
- ALOGV("signalEndOfInputStream: exec=%d avail=%zu eos=%d",
- mExecuting, mNumFramesAvailable, mEndOfStream);
+ ALOGV("signalEndOfInputStream: executing=%d available=%zu+%d eos=%d",
+ mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
if (mEndOfStream) {
ALOGE("EOS was already signaled");
@@ -1104,7 +1251,7 @@
// stall since no future events are expected.
mEndOfStream = true;
- if (mStopTimeUs == -1 && mExecuting && mNumFramesAvailable == 0) {
+ if (mStopTimeUs == -1 && mExecuting && !haveAvailableBuffers_l()) {
submitEndOfInputStream_l();
}
@@ -1125,17 +1272,16 @@
break;
}
- if (!mExecuting || mNumFramesAvailable > 0) {
+ if (!mExecuting || haveAvailableBuffers_l()) {
break;
}
bool success = repeatLatestBuffer_l();
-
if (success) {
ALOGV("repeatLatestBuffer_l SUCCESS");
} else {
ALOGV("repeatLatestBuffer_l FAILURE");
- mRepeatBufferDeferred = true;
+ mFrameRepeatBlockedOnCodecBuffer = true;
}
break;
}
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index ab52ce2..635cfd6 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -41,7 +41,8 @@
struct FrameDropper;
/*
- * This class is used to feed OMX codecs from a Surface via BufferQueue.
+ * This class is used to feed OMX codecs from a Surface via BufferQueue or
+ * HW producer.
*
* Instances of the class don't run on a dedicated thread. Instead,
* various events trigger data movement:
@@ -55,6 +56,22 @@
* Frames of data (and, perhaps, the end-of-stream indication) can arrive
* before the codec is in the "executing" state, so we need to queue
* things up until we're ready to go.
+ *
+ * The GraphicBufferSource can be configure dynamically to discard frames
+ * from the source:
+ *
+ * - if their timestamp is less than a start time
+ * - if the source is suspended or stopped and the suspend/stop-time is reached
+ * - if EOS was signaled
+ * - if there is no encoder connected to it
+ *
+ * The source, furthermore, may choose to not encode (drop) frames if:
+ *
+ * - to throttle the frame rate (keep it under a certain limit)
+ *
+ * Finally the source may optionally hold onto the last non-discarded frame
+ * (even if it was dropped) to reencode it after an interval if no further
+ * frames are sent by the producer.
*/
class GraphicBufferSource : public BufferQueue::ConsumerListener {
public:
@@ -74,6 +91,9 @@
return mProducer;
}
+ // OmxBufferSource interface
+ // ------------------------------
+
// This is called when OMX transitions to OMX_StateExecuting, which means
// we can start handing it buffers. If we already have buffers of data
// sitting in the BufferQueue, this will send them to the codec.
@@ -91,12 +111,14 @@
// A "codec buffer", i.e. a buffer that can be used to pass data into
// the encoder, has been allocated. (This call does not call back into
// OMXNodeInstance.)
- Status onInputBufferAdded(int32_t bufferID);
+ Status onInputBufferAdded(int32_t bufferId);
// Called from OnEmptyBufferDone. If we have a BQ buffer available,
// fill it with a new frame of data; otherwise, just mark it as available.
- Status onInputBufferEmptied(
- int32_t bufferID, int fenceFd);
+ Status onInputBufferEmptied(int32_t bufferId, int fenceFd);
+
+ // IGraphicBufferSource interface
+ // ------------------------------
// Configure the buffer source to be used with an OMX node with the default
// data space.
@@ -154,6 +176,9 @@
status_t setColorAspects(int32_t aspectsPacked);
protected:
+ // BQ::ConsumerListener interface
+ // ------------------------------
+
// BufferQueue::ConsumerListener interface, called when a new frame of
// data is available. If we're executing and a codec buffer is
// available, we acquire the buffer, copy the GraphicBuffer reference
@@ -173,71 +198,136 @@
void onSidebandStreamChanged() override;
private:
-
- // Keep track of codec input buffers. They may either be available
- // (mGraphicBuffer == NULL) or in use by the codec.
- struct CodecBuffer {
- IOMX::buffer_id mBufferID;
-
- // buffer producer's frame-number for buffer
- uint64_t mFrameNumber;
-
- // buffer producer's buffer slot for buffer
- int mSlot;
-
- sp<GraphicBuffer> mGraphicBuffer;
- };
-
- // Returns the index of an available codec buffer. If none are
- // available, returns -1. Mutex must be held by caller.
- int findAvailableCodecBuffer_l();
-
- // Returns true if a codec buffer is available.
- bool isCodecBufferAvailable_l() {
- return findAvailableCodecBuffer_l() >= 0;
- }
-
- // Finds the mCodecBuffers entry that matches. Returns -1 if not found.
- int findMatchingCodecBuffer_l(IOMX::buffer_id bufferID);
-
- // Fills a codec buffer with a frame from the BufferQueue. This must
- // only be called when we know that a frame of data is ready (i.e. we're
- // in the onFrameAvailable callback, or if we're in codecBufferEmptied
- // and mNumFramesAvailable is nonzero). Returns without doing anything if
- // we don't have a codec buffer available.
- //
- // Returns true if we successfully filled a codec buffer with a BQ buffer.
- bool fillCodecBuffer_l();
-
- // Marks the mCodecBuffers entry as in-use, copies the GraphicBuffer
- // reference into the codec buffer, and submits the data to the codec.
- status_t submitBuffer_l(const BufferItem &item, int cbi);
-
- // Submits an empty buffer, with the EOS flag set. Returns without
- // doing anything if we don't have a codec buffer available.
- void submitEndOfInputStream_l();
-
- // Acquire buffer from the consumer
- status_t acquireBuffer(BufferItem *bi);
-
- bool releaseAllBuffers();
-
- // Release buffer to the consumer
- void releaseBuffer(int id, uint64_t frameNum, const sp<Fence> &fence);
-
- void setLatestBuffer_l(const BufferItem &item);
- bool repeatLatestBuffer_l();
- bool getTimestamp(const BufferItem &item, int64_t *codecTimeUs);
-
- // called when the data space of the input buffer changes
- void onDataSpaceChanged_l(android_dataspace dataSpace, android_pixel_format pixelFormat);
-
// Lock, covers all member variables.
mutable Mutex mMutex;
// Used to report constructor failure.
status_t mInitCheck;
+ // Graphic buffer reference objects
+ // --------------------------------
+
+ // These are used to keep a shared reference to GraphicBuffers and gralloc handles owned by the
+ // GraphicBufferSource as well as to manage the cache slots. Separate references are owned by
+ // the buffer cache (controlled by the buffer queue/buffer producer) and the codec.
+
+ // When we get a buffer from the producer (BQ) it designates them to be cached into specific
+ // slots. Each slot owns a shared reference to the graphic buffer (we track these using
+ // CachedBuffer) that is in that slot, but the producer controls the slots.
+ struct CachedBuffer;
+
+ // When we acquire a buffer, we must release it back to the producer once we (or the codec)
+ // no longer uses it (as long as the buffer is still in the cache slot). We use shared
+ // AcquiredBuffer instances for this purpose - and we call release buffer when the last
+ // reference is relinquished.
+ struct AcquiredBuffer;
+
+ // We also need to keep some extra metadata (other than the buffer reference) for acquired
+ // buffers. These are tracked in VideoBuffer struct.
+ struct VideoBuffer {
+ std::shared_ptr<AcquiredBuffer> mBuffer;
+ nsecs_t mTimestampNs;
+ android_dataspace_t mDataspace;
+ };
+
+ // Cached and aquired buffers
+ // --------------------------------
+
+ typedef int slot_id;
+
+ // Maps a slot to the cached buffer in that slot
+ KeyedVector<slot_id, std::shared_ptr<CachedBuffer>> mBufferSlots;
+
+ // Queue of buffers acquired in chronological order that are not yet submitted to the codec
+ List<VideoBuffer> mAvailableBuffers;
+
+ // Number of buffers that have been signaled by the producer that they are available, but
+ // we've been unable to acquire them due to our max acquire count
+ int32_t mNumAvailableUnacquiredBuffers;
+
+ // Number of frames acquired from consumer (debug only)
+ // (as in aquireBuffer called, and release needs to be called)
+ int32_t mNumOutstandingAcquires;
+
+ // Acquire a buffer from the BQ and store it in |item| if successful
+ // \return OK on success, or error on failure.
+ status_t acquireBuffer_l(VideoBuffer *item);
+
+ // Called when a buffer was acquired from the producer
+ void onBufferAcquired_l(const VideoBuffer &buffer);
+
+ // marks the buffer at the slot no longer cached, and accounts for the outstanding
+ // acquire count
+ void discardBufferInSlot_l(slot_id i);
+
+ // marks the buffer at the slot index no longer cached, and accounts for the outstanding
+ // acquire count
+ void discardBufferAtSlotIndex_l(ssize_t bsi);
+
+ // release all acquired and unacquired available buffers
+ // This method will return if it fails to acquire an unacquired available buffer, which will
+ // leave mNumAvailableUnacquiredBuffers positive on return.
+ void releaseAllAvailableBuffers_l();
+
+ // returns whether we have any available buffers (acquired or not-yet-acquired)
+ bool haveAvailableBuffers_l() const {
+ return !mAvailableBuffers.empty() || mNumAvailableUnacquiredBuffers > 0;
+ }
+
+ // Codec buffers
+ // -------------
+
+ // When we queue buffers to the encoder, we must hold the references to the graphic buffers
+ // in those buffers - as the producer may free the slots.
+
+ typedef int32_t codec_buffer_id;
+
+ // set of codec buffer ID-s of buffers available to fill
+ List<codec_buffer_id> mFreeCodecBuffers;
+
+ // maps codec buffer ID-s to buffer info submitted to the codec. Used to keep a reference for
+ // the graphics buffer.
+ KeyedVector<codec_buffer_id, std::shared_ptr<AcquiredBuffer>> mSubmittedCodecBuffers;
+
+ // Processes the next acquired frame. If there is no available codec buffer, it returns false
+ // without any further action.
+ //
+ // Otherwise, it consumes the next acquired frame and determines if it needs to be discarded or
+ // dropped. If neither are needed, it submits it to the codec. It also saves the latest
+ // non-dropped frame and submits it for repeat encoding (if this is enabled).
+ //
+ // \require there must be an acquired frame (i.e. we're in the onFrameAvailable callback,
+ // or if we're in codecBufferEmptied and mNumFramesAvailable is nonzero).
+ // \require codec must be executing
+ // \returns true if acquired (and handled) the next frame. Otherwise, false.
+ bool fillCodecBuffer_l();
+
+ // Calculates the media timestamp for |item| and on success it submits the buffer to the codec,
+ // while also keeping a reference for it in mSubmittedCodecBuffers.
+ // Returns UNKNOWN_ERROR if the buffer was not submitted due to buffer timestamp. Otherwise,
+ // it returns any submit success or error value returned by the codec.
+ status_t submitBuffer_l(const VideoBuffer &item);
+
+ // Submits an empty buffer, with the EOS flag set if there is an available codec buffer and
+ // sets mEndOfStreamSent flag. Does nothing if there is no codec buffer available.
+ void submitEndOfInputStream_l();
+
+ // Set to true if we want to send end-of-stream after we run out of available frames from the
+ // producer
+ bool mEndOfStream;
+
+ // Flag that the EOS was submitted to the encoder
+ bool mEndOfStreamSent;
+
+ // Dataspace for the last frame submitted to the codec
+ android_dataspace mLastDataspace;
+
+ // Default color aspects for this source
+ int32_t mDefaultColorAspectsPacked;
+
+ // called when the data space of the input buffer changes
+ void onDataspaceChanged_l(android_dataspace dataspace, android_pixel_format pixelFormat);
+
// Pointer back to the Omx node that created us. We send buffers here.
sp<IOmxNodeWrapper> mOMXNode;
@@ -246,11 +336,9 @@
bool mSuspended;
- // The time to stop sending buffers.
- int64_t mStopTimeUs;
-
- // Last dataspace seen
- android_dataspace mLastDataSpace;
+ // returns true if this source is unconditionally discarding acquired buffers at the moment
+ // regardless of the metadata of those buffers
+ bool areWeDiscardingAvailableBuffers_l();
// Our BufferQueue interfaces. mProducer is passed to the producer through
// getIGraphicBufferProducer, and mConsumer is used internally to retrieve
@@ -258,26 +346,8 @@
sp<IGraphicBufferProducer> mProducer;
sp<IGraphicBufferConsumer> mConsumer;
- // Number of frames pending in BufferQueue that haven't yet been
- // forwarded to the codec.
- size_t mNumFramesAvailable;
-
- // Number of frames acquired from consumer (debug only)
- int32_t mNumBufferAcquired;
-
- // Set to true if we want to send end-of-stream after we run out of
- // frames in BufferQueue.
- bool mEndOfStream;
- bool mEndOfStreamSent;
-
- // Cache of GraphicBuffers from the buffer queue. When the codec
- // is done processing a GraphicBuffer, we can use this to map back
- // to a slot number.
- sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS];
- int32_t mBufferUseCount[BufferQueue::NUM_BUFFER_SLOTS];
-
- // Tracks codec buffers.
- Vector<CodecBuffer> mCodecBuffers;
+ // The time to stop sending buffers.
+ int64_t mStopTimeUs;
struct ActionItem {
typedef enum {
@@ -302,13 +372,12 @@
friend struct AHandlerReflector<GraphicBufferSource>;
enum {
- kWhatRepeatLastFrame,
+ kWhatRepeatLastFrame, ///< queue last frame for reencoding
};
enum {
kRepeatLastFrameCount = 10,
};
- int64_t mPrevOriginalTimeUs;
int64_t mSkipFramesBeforeNs;
sp<FrameDropper> mFrameDropper;
@@ -316,28 +385,74 @@
sp<ALooper> mLooper;
sp<AHandlerReflector<GraphicBufferSource> > mReflector;
- int64_t mRepeatAfterUs;
- int32_t mRepeatLastFrameGeneration;
- int64_t mRepeatLastFrameTimestamp;
- int32_t mRepeatLastFrameCount;
+ // Repeat last frame feature
+ // -------------------------
+ // configuration parameter: repeat interval for frame repeating (<0 if repeating is disabled)
+ int64_t mFrameRepeatIntervalUs;
- int mLatestBufferId;
- uint64_t mLatestBufferFrameNum;
- sp<Fence> mLatestBufferFence;
+ // current frame repeat generation - used to cancel a pending frame repeat
+ int32_t mRepeatLastFrameGeneration;
+
+ // number of times to repeat latest frame (0 = none)
+ int32_t mOutstandingFrameRepeatCount;
// The previous buffer should've been repeated but
// no codec buffer was available at the time.
- bool mRepeatBufferDeferred;
+ bool mFrameRepeatBlockedOnCodecBuffer;
+
+ // hold a reference to the last acquired (and not discarded) frame for frame repeating
+ VideoBuffer mLatestBuffer;
+
+ // queue last frame for reencode after the repeat interval.
+ void queueFrameRepeat_l();
+
+ // save |item| as the latest buffer and queue it for reencode (repeat)
+ void setLatestBuffer_l(const VideoBuffer &item);
+
+ // submit last frame to encoder and queue it for reencode
+ // \return true if buffer was submitted, false if it wasn't (e.g. source is suspended, there
+ // is no available codec buffer)
+ bool repeatLatestBuffer_l();
// Time lapse / slow motion configuration
+ // --------------------------------------
+
+ // desired time interval between captured frames (capture interval) - value <= 0 if undefined
int64_t mTimePerCaptureUs;
+
+ // desired time interval between encoded frames (media time interval) - value <= 0 if undefined
int64_t mTimePerFrameUs;
+
+ // Time lapse mode is enabled if capture interval is defined and it is more than twice the
+ // media time interval (if defined). In this mode frames that come in between the capture
+ // interval are dropped and the media timestamp is adjusted to have exactly the desired
+ // media time interval.
+ //
+ // Slow motion mode is enabled if both media and capture intervals are defined and the media
+ // time interval is more than twice the capture interval. In this mode frames that come in
+ // between the capture interval are dropped (though there isn't expected to be any, but there
+ // could eventually be a frame drop if the actual capture interval is smaller than the
+ // configured capture interval). The media timestamp is adjusted to have exactly the desired
+ // media time interval.
+
+ // These modes must be enabled before using this source.
+
+ // adjusted capture timestamp for previous frame
int64_t mPrevCaptureUs;
+
+ // adjusted media timestamp for previous frame (negative if there were none)
int64_t mPrevFrameUs;
+ // desired offset between media time and capture time
int64_t mInputBufferTimeOffsetUs;
- int32_t mColorAspectsPacked;
+ // Calculates and outputs the timestamp to use for a buffer with a specific buffer timestamp
+ // |bufferTimestampNs|. Returns false on failure (buffer too close or timestamp is moving
+ // backwards). Otherwise, stores the media timestamp in |*codecTimeUs| and returns true.
+ //
+ // This method takes into account the start time offset and any time lapse or slow motion time
+ // adjustment requests.
+ bool calculateCodecTimestamp_l(nsecs_t bufferTimeNs, int64_t *codecTimeUs);
void onMessageReceived(const sp<AMessage> &msg);
diff --git a/media/libstagefright/omx/hal/1.0/impl/Android.mk b/media/libstagefright/omx/hal/1.0/impl/Android.mk
deleted file mode 100644
index 79cb1fa..0000000
--- a/media/libstagefright/omx/hal/1.0/impl/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := android.hardware.media.omx@1.0-impl
-LOCAL_SRC_FILES := \
- WGraphicBufferSource.cpp \
- WOmxBufferProducer.cpp \
- WOmxBufferSource.cpp \
- WOmxNode.cpp \
- WOmxObserver.cpp \
- WOmxProducerListener.cpp \
- Omx.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libmedia \
- libstagefright_foundation \
- libstagefright_omx \
- libui \
- libgui \
- libhidlbase \
- libhidltransport \
- libhwbinder \
- libhidlmemory \
- libutils \
- libcutils \
- libbinder \
- liblog \
- libbase \
- android.hardware.media.omx@1.0 \
- android.hardware.graphics.common@1.0 \
- android.hardware.media@1.0 \
- android.hidl.base@1.0 \
-
-LOCAL_C_FLAGS += \
- -Wno-unused-parameter \
- -Werror
-
-LOCAL_C_INCLUDES += \
- $(TOP)/frameworks/av/include \
- $(TOP)/frameworks/av/media/libstagefright \
- $(TOP)/frameworks/native/include \
- $(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/frameworks/native/include/media/hardware \
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index ce6354d..e3a23f9 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1040,13 +1040,7 @@
outputDesc->mStopTime[stream] = 0;
outputDesc->mDirectOpenCount = 1;
outputDesc->mDirectClientUid = clientUid;
-
- audio_io_handle_t srcOutput = getOutputForEffect();
addOutput(output, outputDesc);
- audio_io_handle_t dstOutput = getOutputForEffect();
- if (dstOutput == output) {
- mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
- }
mPreviousOutputs = mOutputs;
ALOGV("getOutput() returns new direct output %d", output);
mpClientInterface->onAudioPortListUpdate();
@@ -1254,11 +1248,16 @@
// necessary for a correct control of hardware output routing by startOutput() and stopOutput()
outputDesc->changeRefCount(stream, 1);
+ if (stream == AUDIO_STREAM_MUSIC) {
+ selectOutputForMusicEffects();
+ }
+
if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
// starting an output being rerouted?
if (device == AUDIO_DEVICE_NONE) {
device = getNewOutputDevice(outputDesc, false /*fromCache*/);
}
+
routing_strategy strategy = getStrategy(stream);
bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
(strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
@@ -1411,6 +1410,9 @@
// update the outputs if stopping one with a stream that can affect notification routing
handleNotificationRoutingForStream(stream);
}
+ if (stream == AUDIO_STREAM_MUSIC) {
+ selectOutputForMusicEffects();
+ }
return NO_ERROR;
} else {
ALOGW("stopOutput() refcount is already 0");
@@ -1454,13 +1456,6 @@
}
if (--desc->mDirectOpenCount == 0) {
closeOutput(output);
- // If effects where present on the output, audioflinger moved them to the primary
- // output by default: move them back to the appropriate output.
- audio_io_handle_t dstOutput = getOutputForEffect();
- if (hasPrimaryOutput() && dstOutput != mPrimaryOutput->mIoHandle) {
- mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX,
- mPrimaryOutput->mIoHandle, dstOutput);
- }
mpClientInterface->onAudioPortListUpdate();
}
}
@@ -1633,6 +1628,8 @@
isSoundTrigger,
policyMix, mpClientInterface);
+// FIXME: disable concurrent capture until UI is ready
+#if 0
// reuse an open input if possible
sp<AudioInputDescriptor> reusedInputDesc;
for (size_t i = 0; i < mInputs.size(); i++) {
@@ -1695,6 +1692,7 @@
releaseInput(reusedInputDesc->mIoHandle, currentSession);
}
}
+#endif
audio_config_t config = AUDIO_CONFIG_INITIALIZER;
config.sample_rate = profileSamplingRate;
@@ -1800,6 +1798,8 @@
return BAD_VALUE;
}
+// FIXME: disable concurrent capture until UI is ready
+#if 0
if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
ALOGW("startInput(%d) failed: other input already started", input);
return INVALID_OPERATION;
@@ -1811,6 +1811,70 @@
if (mInputs.activeInputsCountOnDevices() != 0) {
*concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
}
+#else
+ if (!is_virtual_input_device(inputDesc->mDevice)) {
+ if (mCallTxPatch != 0 &&
+ inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
+ ALOGW("startInput(%d) failed: call in progress", input);
+ return INVALID_OPERATION;
+ }
+
+ Vector< sp<AudioInputDescriptor> > activeInputs = mInputs.getActiveInputs();
+ for (size_t i = 0; i < activeInputs.size(); i++) {
+ sp<AudioInputDescriptor> activeDesc = activeInputs[i];
+
+ if (is_virtual_input_device(activeDesc->mDevice)) {
+ continue;
+ }
+
+ audio_source_t activeSource = activeDesc->inputSource(true);
+ if (audioSession->inputSource() == AUDIO_SOURCE_HOTWORD) {
+ if (activeSource == AUDIO_SOURCE_HOTWORD) {
+ if (activeDesc->hasPreemptedSession(session)) {
+ ALOGW("startInput(%d) failed for HOTWORD: "
+ "other input %d already started for HOTWORD",
+ input, activeDesc->mIoHandle);
+ return INVALID_OPERATION;
+ }
+ } else {
+ ALOGV("startInput(%d) failed for HOTWORD: other input %d already started",
+ input, activeDesc->mIoHandle);
+ return INVALID_OPERATION;
+ }
+ } else {
+ if (activeSource != AUDIO_SOURCE_HOTWORD) {
+ ALOGW("startInput(%d) failed: other input %d already started",
+ input, activeDesc->mIoHandle);
+ return INVALID_OPERATION;
+ }
+ }
+ }
+
+ // if capture is allowed, preempt currently active HOTWORD captures
+ for (size_t i = 0; i < activeInputs.size(); i++) {
+ sp<AudioInputDescriptor> activeDesc = activeInputs[i];
+
+ if (is_virtual_input_device(activeDesc->mDevice)) {
+ continue;
+ }
+
+ audio_source_t activeSource = activeDesc->inputSource(true);
+ if (activeSource == AUDIO_SOURCE_HOTWORD) {
+ AudioSessionCollection activeSessions =
+ activeDesc->getAudioSessions(true /*activeOnly*/);
+ audio_session_t activeSession = activeSessions.keyAt(0);
+ audio_io_handle_t activeHandle = activeDesc->mIoHandle;
+ SortedVector<audio_session_t> sessions = activeDesc->getPreemptedSessions();
+ sessions.add(activeSession);
+ inputDesc->setPreemptedSessions(sessions);
+ stopInput(activeHandle, activeSession);
+ releaseInput(activeHandle, activeSession);
+ ALOGV("startInput(%d) for HOTWORD preempting HOTWORD input %d",
+ input, activeDesc->mIoHandle);
+ }
+ }
+ }
+#endif
// increment activity count before calling getNewInputDevice() below as only active sessions
// are considered for device selection
@@ -2116,8 +2180,7 @@
return NO_ERROR;
}
-audio_io_handle_t AudioPolicyManager::selectOutputForEffects(
- const SortedVector<audio_io_handle_t>& outputs)
+audio_io_handle_t AudioPolicyManager::selectOutputForMusicEffects()
{
// select one output among several suitable for global effects.
// The priority is as follows:
@@ -2125,53 +2188,68 @@
// AudioFlinger will invalidate the track and the offloaded output
// will be closed causing the effect to be moved to a PCM output.
// 2: A deep buffer output
- // 3: the first output in the list
-
- if (outputs.size() == 0) {
- return 0;
- }
-
- audio_io_handle_t outputOffloaded = 0;
- audio_io_handle_t outputDeepBuffer = 0;
-
- for (size_t i = 0; i < outputs.size(); i++) {
- sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
- ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
- if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
- outputOffloaded = outputs[i];
- }
- if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
- outputDeepBuffer = outputs[i];
- }
- }
-
- ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
- outputOffloaded, outputDeepBuffer);
- if (outputOffloaded != 0) {
- return outputOffloaded;
- }
- if (outputDeepBuffer != 0) {
- return outputDeepBuffer;
- }
-
- return outputs[0];
-}
-
-audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
-{
- // apply simple rule where global effects are attached to the same output as MUSIC streams
+ // 3: The primary output
+ // 4: the first output in the list
routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
- SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
+ SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
- audio_io_handle_t output = selectOutputForEffects(dstOutputs);
- ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
- output, (desc == NULL) ? "unspecified" : desc->name, (desc == NULL) ? 0 : desc->flags);
+ if (outputs.size() == 0) {
+ return AUDIO_IO_HANDLE_NONE;
+ }
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ bool activeOnly = true;
+
+ while (output == AUDIO_IO_HANDLE_NONE) {
+ audio_io_handle_t outputOffloaded = AUDIO_IO_HANDLE_NONE;
+ audio_io_handle_t outputDeepBuffer = AUDIO_IO_HANDLE_NONE;
+ audio_io_handle_t outputPrimary = AUDIO_IO_HANDLE_NONE;
+
+ for (size_t i = 0; i < outputs.size(); i++) {
+ sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
+ if (activeOnly && !desc->isStreamActive(AUDIO_STREAM_MUSIC)) {
+ continue;
+ }
+ ALOGV("selectOutputForMusicEffects activeOnly %d outputs[%zu] flags 0x%08x",
+ activeOnly, i, desc->mFlags);
+ if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
+ outputOffloaded = outputs[i];
+ }
+ if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
+ outputDeepBuffer = outputs[i];
+ }
+ if ((desc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) != 0) {
+ outputPrimary = outputs[i];
+ }
+ }
+ if (outputOffloaded != AUDIO_IO_HANDLE_NONE) {
+ output = outputOffloaded;
+ } else if (outputDeepBuffer != AUDIO_IO_HANDLE_NONE) {
+ output = outputDeepBuffer;
+ } else if (outputPrimary != AUDIO_IO_HANDLE_NONE) {
+ output = outputPrimary;
+ } else {
+ output = outputs[0];
+ }
+ activeOnly = false;
+ }
+
+ if (output != mMusicEffectOutput) {
+ mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mMusicEffectOutput, output);
+ mMusicEffectOutput = output;
+ }
+
+ ALOGV("selectOutputForMusicEffects selected output %d", output);
return output;
}
+audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc __unused)
+{
+ return selectOutputForMusicEffects();
+}
+
status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
audio_io_handle_t io,
uint32_t strategy,
@@ -3368,7 +3446,8 @@
mBeaconPlayingRefCount(0),
mBeaconMuted(false),
mTtsOutputAvailable(false),
- mMasterMono(false)
+ mMasterMono(false),
+ mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
mUidCached = getuid();
mpClientInterface = clientInterface;
@@ -3813,12 +3892,14 @@
outputDesc->setIoHandle(output);
mOutputs.add(output, outputDesc);
updateMono(output); // update mono status when adding to output list
+ selectOutputForMusicEffects();
nextAudioPortGeneration();
}
void AudioPolicyManager::removeOutput(audio_io_handle_t output)
{
mOutputs.removeItem(output);
+ selectOutputForMusicEffects();
}
void AudioPolicyManager::addInput(audio_io_handle_t input, const sp<AudioInputDescriptor>& inputDesc)
@@ -4406,22 +4487,7 @@
// Move effects associated to this strategy from previous output to new output
if (strategy == STRATEGY_MEDIA) {
- audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
- SortedVector<audio_io_handle_t> moved;
- for (size_t i = 0; i < mEffects.size(); i++) {
- sp<EffectDescriptor> effectDesc = mEffects.valueAt(i);
- if (effectDesc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
- effectDesc->mIo != fxOutput) {
- if (moved.indexOf(effectDesc->mIo) < 0) {
- ALOGV("checkOutputForStrategy() moving effect %d to output %d",
- mEffects.keyAt(i), fxOutput);
- mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, effectDesc->mIo,
- fxOutput);
- moved.add(effectDesc->mIo);
- }
- effectDesc->mIo = fxOutput;
- }
- }
+ selectOutputForMusicEffects();
}
// Move tracks associated to this strategy from previous output to new output
for (int i = 0; i < AUDIO_STREAM_FOR_POLICY_CNT; i++) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 3dfcde6..9e552d7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -452,7 +452,7 @@
audio_channel_mask_t channelMask,
audio_output_flags_t flags);
- audio_io_handle_t selectOutputForEffects(const SortedVector<audio_io_handle_t>& outputs);
+ audio_io_handle_t selectOutputForMusicEffects();
virtual status_t addAudioPatch(audio_patch_handle_t handle, const sp<AudioPatch>& patch)
{
@@ -570,6 +570,8 @@
bool mMasterMono; // true if we wish to force all outputs to mono
AudioPolicyMixCollection mPolicyMixes; // list of registered mixes
+ audio_io_handle_t mMusicEffectOutput; // output selected for music effects
+
#ifdef AUDIO_POLICY_TEST
Mutex mLock;
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index b2686bf..1c78a08 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -940,7 +940,7 @@
CameraParameters::FALSE);
}
- bool isZslReprocessPresent = false;
+ isZslReprocessPresent = false;
camera_metadata_ro_entry_t availableCapabilities =
staticInfo(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
if (0 < availableCapabilities.count) {
@@ -999,7 +999,7 @@
return NO_INIT;
}
- // Get supported preview fps ranges.
+ // Get supported preview fps ranges, up to default maximum.
Vector<Size> supportedPreviewSizes;
Vector<FpsRange> supportedPreviewFpsRanges;
const Size PREVIEW_SIZE_BOUND = { MAX_PREVIEW_WIDTH, MAX_PREVIEW_HEIGHT };
@@ -1007,7 +1007,8 @@
if (res != OK) return res;
for (size_t i=0; i < availableFpsRanges.count; i += 2) {
if (!isFpsSupported(supportedPreviewSizes,
- HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, availableFpsRanges.data.i32[i+1])) {
+ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, availableFpsRanges.data.i32[i+1]) ||
+ availableFpsRanges.data.i32[i+1] > MAX_DEFAULT_FPS) {
continue;
}
FpsRange fpsRange = {availableFpsRanges.data.i32[i], availableFpsRanges.data.i32[i+1]};
@@ -1436,30 +1437,43 @@
*
* Either way, in case of multiple ranges, break the tie by
* selecting the smaller range.
+ *
+ * Always select range within 30fps if one exists.
*/
// all ranges which have previewFps
Vector<Range> candidateRanges;
+ Vector<Range> candidateFastRanges;
for (i = 0; i < availableFrameRates.count; i+=2) {
Range r = {
availableFrameRates.data.i32[i],
availableFrameRates.data.i32[i+1]
};
+ if (!isFpsSupported(availablePreviewSizes,
+ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, r.max)) {
+ continue;
+ }
if (r.min <= previewFps && previewFps <= r.max) {
- candidateRanges.push(r);
+ if (r.max <= MAX_DEFAULT_FPS) {
+ candidateRanges.push(r);
+ } else {
+ candidateFastRanges.push(r);
+ }
}
}
- if (candidateRanges.isEmpty()) {
+ if (candidateRanges.isEmpty() && candidateFastRanges.isEmpty()) {
ALOGE("%s: Requested preview frame rate %d is not supported",
__FUNCTION__, previewFps);
return BAD_VALUE;
}
- // most applicable range with targetFps
- Range bestRange = candidateRanges[0];
- for (i = 1; i < candidateRanges.size(); ++i) {
- Range r = candidateRanges[i];
+ // most applicable range with targetFps
+ Vector<Range>& ranges =
+ candidateRanges.size() > 0 ? candidateRanges : candidateFastRanges;
+ Range bestRange = ranges[0];
+ for (i = 1; i < ranges.size(); ++i) {
+ Range r = ranges[i];
// Find by largest minIndex in recording mode
if (validatedParams.recordingHint) {
if (r.min > bestRange.min) {
@@ -1977,6 +1991,19 @@
paramsFlattened = newParams.flatten();
params = newParams;
+ slowJpegMode = false;
+ Size pictureSize = { pictureWidth, pictureHeight };
+ int64_t minFrameDurationNs = getJpegStreamMinFrameDurationNs(pictureSize);
+ if (previewFpsRange[1] > 1e9/minFrameDurationNs + FPS_MARGIN) {
+ slowJpegMode = true;
+ }
+ if (slowJpegMode || property_get_bool("camera.disable_zsl_mode", false)) {
+ allowZslMode = false;
+ } else {
+ allowZslMode = isZslReprocessPresent;
+ }
+ ALOGV("%s: allowZslMode: %d slowJpegMode %d", __FUNCTION__, allowZslMode, slowJpegMode);
+
return OK;
}
@@ -2984,7 +3011,6 @@
}
// Get min frame duration for each size and check if the given fps range can be supported.
- const int32_t FPS_MARGIN = 1;
for (size_t i = 0 ; i < sizes.size(); i++) {
int64_t minFrameDuration = getMinFrameDurationNs(sizes[i], format);
if (minFrameDuration <= 0) {
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index 507de75..bea867a 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -173,6 +173,8 @@
// Whether the jpeg stream is slower than 30FPS and can slow down preview.
// When slowJpegMode is true, allowZslMode must be false to avoid slowing down preview.
bool slowJpegMode;
+ // Whether ZSL reprocess is supported by the device.
+ bool isZslReprocessPresent;
// Overall camera state
enum State {
@@ -199,6 +201,10 @@
static const CONSTEXPR float ASPECT_RATIO_TOLERANCE = 0.001;
// Threshold for slow jpeg mode
static const int64_t kSlowJpegModeThreshold = 33400000LL; // 33.4 ms
+ // Margin for checking FPS
+ static const int32_t FPS_MARGIN = 1;
+ // Max FPS for default parameters
+ static const int32_t MAX_DEFAULT_FPS = 30;
// Full static camera info, object owned by someone else, such as
// Camera2Device.
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index a77a90b7..f2e8df8 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1269,6 +1269,13 @@
surfaceId++;
}
+ // Gracefully handle case where finalizeOutputConfigurations is called
+ // without any new surface.
+ if (consumerSurfaces.size() == 0) {
+ mStreamInfoMap[streamId].finalized = true;
+ return res;
+ }
+
// Finish the deferred stream configuration with the surface.
status_t err;
err = mDevice->setConsumerSurfaces(streamId, consumerSurfaces);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 56ba5b6..f3a81cb 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -912,8 +912,15 @@
if (s == Status::OK) {
camera_metadata_t *buffer =
reinterpret_cast<camera_metadata_t*>(metadata.data());
- set_camera_metadata_vendor_id(buffer, mProviderTagid);
- mCameraCharacteristics = buffer;
+ size_t expectedSize = metadata.size();
+ int res = validate_camera_metadata_structure(buffer, &expectedSize);
+ if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
+ set_camera_metadata_vendor_id(buffer, mProviderTagid);
+ mCameraCharacteristics = buffer;
+ } else {
+ ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
+ status = Status::INTERNAL_ERROR;
+ }
}
});
if (!ret.isOk()) {
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
index 0fe09d9..9df7cd4 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -17,6 +17,7 @@
//#define LOG_NDEBUG 0
#include <inttypes.h>
+#include <media/hardware/HardwareAPI.h> // For VideoNativeHandleMetadata
#include "CameraHardwareInterface.h"
namespace android {
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 4bd879f..907065f 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -317,16 +317,6 @@
const camera_memory_t *data, unsigned index,
void *user);
- // TODO: b/35625849
- // Meta data buffer layout for passing a native_handle to codec
- // matching frameworks/native/include/media/hardware/MetadataBufferType.h and
- // frameworks/native/include/media/hardware/HardwareAPI.h
- struct VideoNativeHandleMetadata {
- static const uint32_t kMetadataBufferTypeNativeHandleSource = 3;
- uint32_t eType; // must be kMetadataBufferTypeNativeHandleSource
- native_handle_t* pHandle;
- };
-
// This is a utility class that combines a MemoryHeapBase and a MemoryBase
// in one. Since we tend to use them in a one-to-one relationship, this is
// handy.
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index ab077f0..b64488c 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -3180,7 +3180,7 @@
reinterpret_cast<const camera_metadata_t*>(request.data());
size_t expectedSize = request.size();
int ret = validate_camera_metadata_structure(r, &expectedSize);
- if (ret == OK) {
+ if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
*requestTemplate = clone_camera_metadata(r);
if (*requestTemplate == nullptr) {
ALOGE("%s: Unable to clone camera metadata received from HAL",