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",