summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/stagefright/MediaDefs.h1
-rw-r--r--include/ndk/NdkMediaCodec.h58
-rw-r--r--include/ndk/NdkMediaCrypto.h1
-rw-r--r--include/ndk/NdkMediaDrm.h46
-rw-r--r--include/ndk/NdkMediaExtractor.h11
-rw-r--r--include/ndk/NdkMediaMuxer.h47
-rw-r--r--include/private/media/AudioTrackShared.h14
-rw-r--r--media/libeffects/downmix/EffectDownmix.c7
-rw-r--r--media/libeffects/preprocessing/PreProcessing.cpp6
-rw-r--r--media/libeffects/visualizer/EffectVisualizer.cpp3
-rw-r--r--media/libmedia/AudioRecord.cpp5
-rw-r--r--media/libmedia/AudioTrack.cpp15
-rw-r--r--media/libmedia/AudioTrackShared.cpp2
-rw-r--r--media/libmediaplayerservice/MediaPlayerFactory.cpp2
-rw-r--r--media/libnbaio/AudioStreamInSource.cpp3
-rw-r--r--media/libnbaio/AudioStreamOutSink.cpp3
-rw-r--r--media/libstagefright/ACodec.cpp3
-rw-r--r--media/libstagefright/MediaDefs.cpp1
-rw-r--r--media/mediaserver/Android.mk3
-rw-r--r--media/ndk/NdkMediaCodec.cpp15
-rw-r--r--media/ndk/NdkMediaDrm.cpp163
-rw-r--r--media/ndk/NdkMediaExtractor.cpp16
-rw-r--r--media/ndk/NdkMediaMuxer.cpp6
-rw-r--r--services/audioflinger/AudioFlinger.cpp6
-rw-r--r--services/audioflinger/AudioFlinger.h3
-rw-r--r--services/audioflinger/AudioMixer.cpp19
-rw-r--r--services/audioflinger/AudioMixer.h4
-rw-r--r--services/audioflinger/Effects.h1
-rw-r--r--services/audioflinger/FastMixer.cpp18
-rw-r--r--services/audioflinger/FastMixerState.h6
-rw-r--r--services/audioflinger/PlaybackTracks.h2
-rw-r--r--services/audioflinger/Threads.cpp57
-rw-r--r--services/audioflinger/Tracks.cpp35
-rw-r--r--services/audiopolicy/AudioPolicyManager.cpp12
34 files changed, 397 insertions, 197 deletions
diff --git a/include/media/stagefright/MediaDefs.h b/include/media/stagefright/MediaDefs.h
index 678d642..563c0b5 100644
--- a/include/media/stagefright/MediaDefs.h
+++ b/include/media/stagefright/MediaDefs.h
@@ -25,6 +25,7 @@ extern const char *MEDIA_MIMETYPE_IMAGE_JPEG;
extern const char *MEDIA_MIMETYPE_VIDEO_VP8;
extern const char *MEDIA_MIMETYPE_VIDEO_VP9;
extern const char *MEDIA_MIMETYPE_VIDEO_AVC;
+extern const char *MEDIA_MIMETYPE_VIDEO_HEVC;
extern const char *MEDIA_MIMETYPE_VIDEO_MPEG4;
extern const char *MEDIA_MIMETYPE_VIDEO_H263;
extern const char *MEDIA_MIMETYPE_VIDEO_MPEG2;
diff --git a/include/ndk/NdkMediaCodec.h b/include/ndk/NdkMediaCodec.h
index dd869f6..2f000d7 100644
--- a/include/ndk/NdkMediaCodec.h
+++ b/include/ndk/NdkMediaCodec.h
@@ -146,10 +146,22 @@ ssize_t AMediaCodec_dequeueOutputBuffer(AMediaCodec*, AMediaCodecBufferInfo *inf
AMediaFormat* AMediaCodec_getOutputFormat(AMediaCodec*);
/**
- * Release and optionally render the specified buffer.
+ * If you are done with a buffer, use this call to return the buffer to
+ * the codec. If you previously specified a surface when configuring this
+ * video decoder you can optionally render the buffer.
*/
media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec*, size_t idx, bool render);
+/**
+ * If you are done with a buffer, use this call to update its surface timestamp
+ * and return it to the codec to render it on the output surface. If you
+ * have not specified an output surface when configuring this video codec,
+ * this call will simply return the buffer to the codec.
+ *
+ * For more details, see the Java documentation for MediaCodec.releaseOutputBuffer.
+ */
+media_status_t AMediaCodec_releaseOutputBufferAtTime(
+ AMediaCodec *mData, size_t idx, int64_t timestampNs);
typedef void (*OnCodecEvent)(AMediaCodec *codec, void *userdata);
@@ -163,20 +175,30 @@ media_status_t AMediaCodec_setNotificationCallback(
AMediaCodec*, OnCodecEvent callback, void *userdata);
-enum {
+typedef enum {
AMEDIACODECRYPTOINFO_MODE_CLEAR = 0,
AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1
-};
+} cryptoinfo_mode_t;
/**
- * create an AMediaCodecCryptoInfo from scratch. Use this if you need to use custom
+ * Create an AMediaCodecCryptoInfo from scratch. Use this if you need to use custom
* crypto info, rather than one obtained from AMediaExtractor.
+ *
+ * AMediaCodecCryptoInfo describes the structure of an (at least
+ * partially) encrypted input sample.
+ * A buffer's data is considered to be partitioned into "subsamples",
+ * each subsample starts with a (potentially empty) run of plain,
+ * unencrypted bytes followed by a (also potentially empty) run of
+ * encrypted bytes.
+ * numBytesOfClearData can be null to indicate that all data is encrypted.
+ * This information encapsulates per-sample metadata as outlined in
+ * ISO/IEC FDIS 23001-7:2011 "Common encryption in ISO base media file format files".
*/
AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
int numsubsamples,
uint8_t key[16],
uint8_t iv[16],
- uint32_t mode,
+ cryptoinfo_mode_t mode,
size_t *clearbytes,
size_t *encryptedbytes);
@@ -186,11 +208,35 @@ AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
*/
media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo*);
+/**
+ * The number of subsamples that make up the buffer's contents.
+ */
size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo*);
+
+/**
+ * A 16-byte opaque key
+ */
media_status_t AMediaCodecCryptoInfo_getKey(AMediaCodecCryptoInfo*, uint8_t *dst);
+
+/**
+ * A 16-byte initialization vector
+ */
media_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo*, uint8_t *dst);
-uint32_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo*);
+
+/**
+ * The type of encryption that has been applied,
+ * one of AMEDIACODECRYPTOINFO_MODE_CLEAR or AMEDIACODECRYPTOINFO_MODE_AES_CTR.
+ */
+cryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo*);
+
+/**
+ * The number of leading unencrypted bytes in each subsample.
+ */
media_status_t AMediaCodecCryptoInfo_getClearBytes(AMediaCodecCryptoInfo*, size_t *dst);
+
+/**
+ * The number of trailing encrypted bytes in each subsample.
+ */
media_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo*, size_t *dst);
#ifdef __cplusplus
diff --git a/include/ndk/NdkMediaCrypto.h b/include/ndk/NdkMediaCrypto.h
index 83eaad2..90374c5 100644
--- a/include/ndk/NdkMediaCrypto.h
+++ b/include/ndk/NdkMediaCrypto.h
@@ -29,6 +29,7 @@
#define _NDK_MEDIA_CRYPTO_H
#include <sys/types.h>
+#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
diff --git a/include/ndk/NdkMediaDrm.h b/include/ndk/NdkMediaDrm.h
index 04c371c..10afdd9 100644
--- a/include/ndk/NdkMediaDrm.h
+++ b/include/ndk/NdkMediaDrm.h
@@ -27,7 +27,7 @@
#ifndef _NDK_MEDIA_DRM_H
#define _NDK_MEDIA_DRM_H
-#include <NdkMediaError.h>
+#include "NdkMediaError.h"
#ifdef __cplusplus
extern "C" {
@@ -77,7 +77,7 @@ typedef enum AMediaDrmEventType {
EVENT_VENDOR_DEFINED = 4
} AMediaDrmEventType;
-typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId &sessionId,
+typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId *sessionId,
AMediaDrmEventType eventType, int extra, const uint8_t *data, size_t dataSize);
@@ -115,13 +115,13 @@ media_status_t AMediaDrm_setOnEventListener(AMediaDrm *, AMediaDrmEventListener
* returns MEDIADRM_NOT_PROVISIONED_ERROR if provisioning is needed
* returns MEDIADRM_RESOURCE_BUSY_ERROR if required resources are in use
*/
-media_status_t AMediaDrm_openSession(AMediaDrm *, AMediaDrmSessionId &sessionId);
+media_status_t AMediaDrm_openSession(AMediaDrm *, AMediaDrmSessionId *sessionId);
/**
* Close a session on the MediaDrm object that was previously opened
* with AMediaDrm_openSession.
*/
-media_status_t AMediaDrm_closeSession(AMediaDrm *, const AMediaDrmSessionId &sessionId);
+media_status_t AMediaDrm_closeSession(AMediaDrm *, const AMediaDrmSessionId *sessionId);
typedef enum AMediaDrmKeyType {
/**
@@ -198,10 +198,10 @@ typedef struct AMediaDrmKeyValuePair {
* returns MEDIADRM_NOT_PROVISIONED_ERROR if reprovisioning is needed, due to a
* problem with the device certificate.
*/
-media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope &scope,
+media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope *scope,
const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
- const uint8_t *&keyRequest, size_t &keyRequestSize);
+ const uint8_t **keyRequest, size_t *keyRequestSize);
/**
* A key response is received from the license server by the app, then it is
@@ -220,8 +220,8 @@ media_status_t AMediaDrm_getKeyRequest(AMediaDrm *, const AMediaDrmScope &scope,
* responseSize should be set to the size of the response in bytes
*/
-media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope &scope,
- const uint8_t *response, size_t responseSize, AMediaDrmKeySetId &keySetId);
+media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope *scope,
+ const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId);
/**
* Restore persisted offline keys into a new session. keySetId identifies the
@@ -230,15 +230,15 @@ media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *, const AMediaDrmScope &s
* sessionId is the session ID for the DRM session
* keySetId identifies the saved key set to restore
*/
-media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId &sessionId,
- const AMediaDrmKeySetId &keySetId);
+media_status_t AMediaDrm_restoreKeys(AMediaDrm *, const AMediaDrmSessionId *sessionId,
+ const AMediaDrmKeySetId *keySetId);
/**
* Remove the current keys from a session.
*
* keySetId identifies keys to remove
*/
-media_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId &keySetId);
+media_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId *keySetId);
/**
* Request an informative description of the key status for the session. The status is
@@ -253,8 +253,8 @@ media_status_t AMediaDrm_removeKeys(AMediaDrm *, const AMediaDrmSessionId &keySe
* to be returned is greater than *numPairs, MEDIADRM_SHORT_BUFFER will be returned
* and numPairs will be set to the number of pairs available.
*/
-media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId &sessionId,
- AMediaDrmKeyValue *keyValuePairs, size_t &numPairs);
+media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId *sessionId,
+ AMediaDrmKeyValue *keyValuePairs, size_t *numPairs);
/**
@@ -272,8 +272,8 @@ media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *, const AMediaDrmSessionId &s
* the provisioning request should be sent to. It will remain accessible until
* the next call to getProvisionRequest.
*/
-media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t *&provisionRequest,
- size_t &provisionRequestSize, const char *&serverUrl);
+media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *, const uint8_t **provisionRequest,
+ size_t *provisionRequestSize, const char **serverUrl);
/**
@@ -313,7 +313,7 @@ media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *,
* number required.
*/
media_status_t AMediaDrm_getSecureStops(AMediaDrm *,
- AMediaDrmSecureStop *secureStops, size_t &numSecureStops);
+ AMediaDrmSecureStop *secureStops, size_t *numSecureStops);
/**
* Process the SecureStop server response message ssRelease. After authenticating
@@ -322,7 +322,7 @@ media_status_t AMediaDrm_getSecureStops(AMediaDrm *,
* ssRelease is the server response indicating which secure stops to release
*/
media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *,
- const AMediaDrmSecureStop &ssRelease);
+ const AMediaDrmSecureStop *ssRelease);
/**
* String property name: identifies the maker of the DRM engine plugin
@@ -355,7 +355,7 @@ const char *PROPERTY_ALGORITHMS = "algorithms";
* will remain valid until the next call to AMediaDrm_getPropertyString.
*/
media_status_t AMediaDrm_getPropertyString(AMediaDrm *, const char *propertyName,
- const char *&propertyValue);
+ const char **propertyValue);
/**
* Byte array property name: the device unique identifier is established during
@@ -370,7 +370,7 @@ const char *PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
* will remain valid until the next call to AMediaDrm_getPropertyByteArray.
*/
media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *, const char *propertyName,
- AMediaDrmByteArray &propertyValue);
+ AMediaDrmByteArray *propertyValue);
/**
* Set a DRM engine plugin String property value.
@@ -409,7 +409,7 @@ media_status_t AMediaDrm_setPropertyByteArray(AMediaDrm *, const char *propertyN
* to use is identified by the 16 byte keyId. The key must have been loaded into
* the session using provideKeyResponse.
*/
-media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
const uint8_t *input, uint8_t *output, size_t dataSize);
@@ -420,7 +420,7 @@ media_status_t AMediaDrm_encrypt(AMediaDrm *, const AMediaDrmSessionId &sessionI
* to use is identified by the 16 byte keyId. The key must have been loaded into
* the session using provideKeyResponse.
*/
-media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
const uint8_t *input, uint8_t *output, size_t dataSize);
@@ -433,7 +433,7 @@ media_status_t AMediaDrm_decrypt(AMediaDrm *, const AMediaDrmSessionId &sessionI
* by the 16 byte keyId. The key must have been loaded into the session using
* provideKeyResponse.
*/
-media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
uint8_t *signature, size_t *signatureSize);
@@ -444,7 +444,7 @@ media_status_t AMediaDrm_sign(AMediaDrm *, const AMediaDrmSessionId &sessionId,
* use is identified by the 16 byte keyId. The key must have been loaded into the
* session using provideKeyResponse.
*/
-media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_verify(AMediaDrm *, const AMediaDrmSessionId *sessionId,
const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
const uint8_t *signature, size_t signatureSize);
diff --git a/include/ndk/NdkMediaExtractor.h b/include/ndk/NdkMediaExtractor.h
index 2ba69fb..5a319d7 100644
--- a/include/ndk/NdkMediaExtractor.h
+++ b/include/ndk/NdkMediaExtractor.h
@@ -114,6 +114,16 @@ int64_t AMediaExtractor_getSampletime(AMediaExtractor*);
*/
bool AMediaExtractor_advance(AMediaExtractor*);
+typedef enum {
+ AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC,
+ AMEDIAEXTRACTOR_SEEK_NEXT_SYNC,
+ AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC
+} SeekMode;
+
+/**
+ *
+ */
+media_status_t AMediaExtractor_seekTo(AMediaExtractor*, int64_t seekPosUs, SeekMode mode);
/**
* mapping of crypto scheme uuid to the scheme specific data for that scheme
@@ -146,7 +156,6 @@ enum {
AMEDIAEXTRACTOR_SAMPLE_FLAG_ENCRYPTED = 2,
};
-
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/include/ndk/NdkMediaMuxer.h b/include/ndk/NdkMediaMuxer.h
index db183e9..90d946c 100644
--- a/include/ndk/NdkMediaMuxer.h
+++ b/include/ndk/NdkMediaMuxer.h
@@ -56,18 +56,61 @@ AMediaMuxer* AMediaMuxer_new(int fd, OutputFormat format);
*/
media_status_t AMediaMuxer_delete(AMediaMuxer*);
-media_status_t AMediaMuxer_setLocation(AMediaMuxer*, float latitude, float longtitude);
+/**
+ * Set and store the geodata (latitude and longitude) in the output file.
+ * This method should be called before AMediaMuxer_start. The geodata is stored
+ * in udta box if the output format is AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4, and is
+ * ignored for other output formats.
+ * The geodata is stored according to ISO-6709 standard.
+ *
+ * Both values are specified in degrees.
+ * Latitude must be in the range [-90, 90].
+ * Longitude must be in the range [-180, 180].
+ */
+media_status_t AMediaMuxer_setLocation(AMediaMuxer*, float latitude, float longitude);
+/**
+ * Sets the orientation hint for output video playback.
+ * This method should be called before AMediaMuxer_start. Calling this
+ * method will not rotate the video frame when muxer is generating the file,
+ * but add a composition matrix containing the rotation angle in the output
+ * video if the output format is AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4, so that a
+ * video player can choose the proper orientation for playback.
+ * Note that some video players may choose to ignore the composition matrix
+ * during playback.
+ * The angle is specified in degrees, clockwise.
+ * The supported angles are 0, 90, 180, and 270 degrees.
+ */
media_status_t AMediaMuxer_setOrientationHint(AMediaMuxer*, int degrees);
+/**
+ * Adds a track with the specified format.
+ * Returns the index of the new track or a negative value in case of failure,
+ * which can be interpreted as a media_status_t.
+ */
ssize_t AMediaMuxer_addTrack(AMediaMuxer*, const AMediaFormat* format);
+/**
+ * Start the muxer. Should be called after AMediaMuxer_addTrack and
+ * before AMediaMuxer_writeSampleData.
+ */
media_status_t AMediaMuxer_start(AMediaMuxer*);
+/**
+ * Stops the muxer.
+ * Once the muxer stops, it can not be restarted.
+ */
media_status_t AMediaMuxer_stop(AMediaMuxer*);
+/**
+ * Writes an encoded sample into the muxer.
+ * The application needs to make sure that the samples are written into
+ * the right tracks. Also, it needs to make sure the samples for each track
+ * are written in chronological order (e.g. in the order they are provided
+ * by the encoder.)
+ */
media_status_t AMediaMuxer_writeSampleData(AMediaMuxer *muxer,
- size_t trackIdx, const uint8_t *data, const AMediaCodecBufferInfo &info);
+ size_t trackIdx, const uint8_t *data, const AMediaCodecBufferInfo *info);
#ifdef __cplusplus
} // extern "C"
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 3901e79..5116d1e 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <audio_utils/minifloat.h>
#include <utils/threads.h>
#include <utils/Log.h>
#include <utils/RefBase.h>
@@ -110,11 +111,8 @@ private:
// force to 32-bit. The client and server may have different typedefs for size_t.
uint32_t mMinimum; // server wakes up client if available >= mMinimum
- // Channel volumes are fixed point U4.12, so 0x1000 means 1.0.
- // Left channel is in [0:15], right channel is in [16:31].
- // Always read and write the combined pair atomically.
- // For AudioTrack only, not used by AudioRecord.
- uint32_t mVolumeLR;
+ // Stereo gains for AudioTrack only, not used by AudioRecord.
+ gain_minifloat_packed_t mVolumeLR;
uint32_t mSampleRate; // AudioTrack only: client's requested sample rate in Hz
// or 0 == default. Write-only client, read-only server.
@@ -285,8 +283,8 @@ public:
mCblk->mSendLevel = uint16_t(sendLevel * 0x1000);
}
- // caller must limit to 0 <= volumeLR <= 0x10001000
- void setVolumeLR(uint32_t volumeLR) {
+ // set stereo gains
+ void setVolumeLR(gain_minifloat_packed_t volumeLR) {
mCblk->mVolumeLR = volumeLR;
}
@@ -405,7 +403,7 @@ public:
// return value of these methods must be validated by the caller
uint32_t getSampleRate() const { return mCblk->mSampleRate; }
uint16_t getSendLevel_U4_12() const { return mCblk->mSendLevel; }
- uint32_t getVolumeLR() const { return mCblk->mVolumeLR; }
+ gain_minifloat_packed_t getVolumeLR() const { return mCblk->mVolumeLR; }
// estimated total number of filled frames available to server to read,
// which may include non-contiguous frames
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index 661fde9..6686f27 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -118,7 +118,7 @@ void Downmix_testIndexComputation(uint32_t mask) {
hasBacks = true;
}
- const int numChan = popcount(mask);
+ const int numChan = audio_channel_count_from_out_mask(mask);
const bool hasFC = ((mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) == AUDIO_CHANNEL_OUT_FRONT_CENTER);
const bool hasLFE =
((mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) == AUDIO_CHANNEL_OUT_LOW_FREQUENCY);
@@ -629,7 +629,8 @@ int Downmix_Configure(downmix_module_t *pDwmModule, effect_config_t *pConfig, bo
ALOGE("Downmix_Configure error: input channel mask can't be 0");
return -EINVAL;
}
- pDownmixer->input_channel_count = popcount(pConfig->inputCfg.channels);
+ pDownmixer->input_channel_count =
+ audio_channel_count_from_out_mask(pConfig->inputCfg.channels);
}
Downmix_Reset(pDownmixer, init);
@@ -997,7 +998,7 @@ bool Downmix_foldGeneric(
hasBacks = true;
}
- const int numChan = popcount(mask);
+ const int numChan = audio_channel_count_from_out_mask(mask);
const bool hasFC = ((mask & AUDIO_CHANNEL_OUT_FRONT_CENTER) == AUDIO_CHANNEL_OUT_FRONT_CENTER);
const bool hasLFE =
((mask & AUDIO_CHANNEL_OUT_LOW_FREQUENCY) == AUDIO_CHANNEL_OUT_LOW_FREQUENCY);
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index a96a703..cf98f56 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -879,8 +879,8 @@ int Session_ReleaseEffect(preproc_session_t *session,
int Session_SetConfig(preproc_session_t *session, effect_config_t *config)
{
uint32_t sr;
- uint32_t inCnl = popcount(config->inputCfg.channels);
- uint32_t outCnl = popcount(config->outputCfg.channels);
+ uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
+ uint32_t outCnl = audio_channel_count_from_out_mask(config->outputCfg.channels);
if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
config->inputCfg.format != config->outputCfg.format ||
@@ -1035,7 +1035,7 @@ int Session_SetReverseConfig(preproc_session_t *session, effect_config_t *config
config->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) {
return -EINVAL;
}
- uint32_t inCnl = popcount(config->inputCfg.channels);
+ uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
int status = session->apm->set_num_reverse_channels(inCnl);
if (status < 0) {
return -EINVAL;
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 47cab62..e5089da 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -207,7 +207,8 @@ int Visualizer_init(VisualizerContext *pContext)
pContext->mScalingMode = VISUALIZER_SCALING_MODE_NORMALIZED;
// measurement initialization
- pContext->mChannelCount = popcount(pContext->mConfig.inputCfg.channels);
+ pContext->mChannelCount =
+ audio_channel_count_from_out_mask(pContext->mConfig.inputCfg.channels);
pContext->mMeasurementMode = MEASUREMENT_MODE_NONE;
pContext->mMeasurementWindowSizeInBuffers = MEASUREMENT_WINDOW_MAX_SIZE_IN_BUFFERS;
pContext->mMeasurementBufferIdx = 0;
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 97ab8f8..1c808d0 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -51,7 +51,8 @@ status_t AudioRecord::getMinFrameCount(
// We double the size of input buffer for ping pong use of record buffer.
// Assumes audio_is_linear_pcm(format)
- if ((*frameCount = (size * 2) / (popcount(channelMask) * audio_bytes_per_sample(format))) == 0) {
+ if ((*frameCount = (size * 2) / (audio_channel_count_from_in_mask(channelMask) *
+ audio_bytes_per_sample(format))) == 0) {
ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
sampleRate, format, channelMask);
return BAD_VALUE;
@@ -193,7 +194,7 @@ status_t AudioRecord::set(
return BAD_VALUE;
}
mChannelMask = channelMask;
- uint32_t channelCount = popcount(channelMask);
+ uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
mChannelCount = channelCount;
if (audio_is_linear_pcm(format)) {
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index aaaa3f1..7d3ecc5 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -19,6 +19,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "AudioTrack"
+#include <math.h>
#include <sys/resource.h>
#include <audio_utils/primitives.h>
#include <binder/IPCThreadState.h>
@@ -290,7 +291,7 @@ status_t AudioTrack::set(
return BAD_VALUE;
}
mChannelMask = channelMask;
- uint32_t channelCount = popcount(channelMask);
+ uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
mChannelCount = channelCount;
// AudioFlinger does not currently support 8-bit data in shared memory
@@ -566,7 +567,9 @@ void AudioTrack::pause()
status_t AudioTrack::setVolume(float left, float right)
{
- if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) {
+ // This duplicates a test by AudioTrack JNI, but that is not the only caller
+ if (isnanf(left) || left < GAIN_FLOAT_ZERO || left > GAIN_FLOAT_UNITY ||
+ isnanf(right) || right < GAIN_FLOAT_ZERO || right > GAIN_FLOAT_UNITY) {
return BAD_VALUE;
}
@@ -574,7 +577,7 @@ status_t AudioTrack::setVolume(float left, float right)
mVolume[AUDIO_INTERLEAVE_LEFT] = left;
mVolume[AUDIO_INTERLEAVE_RIGHT] = right;
- mProxy->setVolumeLR((uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000));
+ mProxy->setVolumeLR(gain_minifloat_pack(gain_from_float(left), gain_from_float(right)));
if (isOffloaded_l()) {
mAudioTrack->signal();
@@ -589,7 +592,8 @@ status_t AudioTrack::setVolume(float volume)
status_t AudioTrack::setAuxEffectSendLevel(float level)
{
- if (level < 0.0f || level > 1.0f) {
+ // This duplicates a test by AudioTrack JNI, but that is not the only caller
+ if (isnanf(level) || level < GAIN_FLOAT_ZERO || level > GAIN_FLOAT_UNITY) {
return BAD_VALUE;
}
@@ -1137,8 +1141,7 @@ status_t AudioTrack::createTrack_l(size_t epoch)
mStaticProxy = new StaticAudioTrackClientProxy(cblk, buffers, frameCount, mFrameSizeAF);
mProxy = mStaticProxy;
}
- mProxy->setVolumeLR((uint32_t(uint16_t(mVolume[AUDIO_INTERLEAVE_RIGHT] * 0x1000)) << 16) |
- uint16_t(mVolume[AUDIO_INTERLEAVE_LEFT] * 0x1000));
+ mProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY);
mProxy->setSendLevel(mSendLevel);
mProxy->setSampleRate(mSampleRate);
mProxy->setEpoch(epoch);
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 323b675..27a3718 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -27,7 +27,7 @@ namespace android {
audio_track_cblk_t::audio_track_cblk_t()
: mServer(0), mFutex(0), mMinimum(0),
- mVolumeLR(0x10001000), mSampleRate(0), mSendLevel(0), mFlags(0)
+ mVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY), mSampleRate(0), mSendLevel(0), mFlags(0)
{
memset(&u, 0, sizeof(u));
}
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index 74e5013..9b239b1 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -186,7 +186,7 @@ class StagefrightPlayerFactory :
read(fd, buf, sizeof(buf));
lseek(fd, offset, SEEK_SET);
- long ident = *((long*)buf);
+ uint32_t ident = *((uint32_t*)buf);
// Ogg vorbis?
if (ident == 0x5367674f) // 'OggS'
diff --git a/media/libnbaio/AudioStreamInSource.cpp b/media/libnbaio/AudioStreamInSource.cpp
index af8f365..6aab48a 100644
--- a/media/libnbaio/AudioStreamInSource.cpp
+++ b/media/libnbaio/AudioStreamInSource.cpp
@@ -46,7 +46,8 @@ ssize_t AudioStreamInSource::negotiate(const NBAIO_Format offers[], size_t numOf
uint32_t sampleRate = mStream->common.get_sample_rate(&mStream->common);
audio_channel_mask_t channelMask =
(audio_channel_mask_t) mStream->common.get_channels(&mStream->common);
- mFormat = Format_from_SR_C(sampleRate, popcount(channelMask), streamFormat);
+ mFormat = Format_from_SR_C(sampleRate,
+ audio_channel_count_from_in_mask(channelMask), streamFormat);
mFrameSize = Format_frameSize(mFormat);
}
return NBAIO_Source::negotiate(offers, numOffers, counterOffers, numCounterOffers);
diff --git a/media/libnbaio/AudioStreamOutSink.cpp b/media/libnbaio/AudioStreamOutSink.cpp
index c28d34d..0d5f935 100644
--- a/media/libnbaio/AudioStreamOutSink.cpp
+++ b/media/libnbaio/AudioStreamOutSink.cpp
@@ -43,7 +43,8 @@ ssize_t AudioStreamOutSink::negotiate(const NBAIO_Format offers[], size_t numOff
uint32_t sampleRate = mStream->common.get_sample_rate(&mStream->common);
audio_channel_mask_t channelMask =
(audio_channel_mask_t) mStream->common.get_channels(&mStream->common);
- mFormat = Format_from_SR_C(sampleRate, popcount(channelMask), streamFormat);
+ mFormat = Format_from_SR_C(sampleRate,
+ audio_channel_count_from_out_mask(channelMask), streamFormat);
mFrameSize = Format_frameSize(mFormat);
}
return NBAIO_Sink::negotiate(offers, numOffers, counterOffers, numCounterOffers);
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 2e8e412..8f154be 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -990,6 +990,8 @@ status_t ACodec::setComponentRole(
"audio_decoder.g711alaw", "audio_encoder.g711alaw" },
{ MEDIA_MIMETYPE_VIDEO_AVC,
"video_decoder.avc", "video_encoder.avc" },
+ { MEDIA_MIMETYPE_VIDEO_HEVC,
+ "video_decoder.hevc", "video_encoder.hevc" },
{ MEDIA_MIMETYPE_VIDEO_MPEG4,
"video_decoder.mpeg4", "video_encoder.mpeg4" },
{ MEDIA_MIMETYPE_VIDEO_H263,
@@ -1811,6 +1813,7 @@ static const struct VideoCodingMapEntry {
OMX_VIDEO_CODINGTYPE mVideoCodingType;
} kVideoCodingMapEntry[] = {
{ MEDIA_MIMETYPE_VIDEO_AVC, OMX_VIDEO_CodingAVC },
+ { MEDIA_MIMETYPE_VIDEO_HEVC, OMX_VIDEO_CodingHEVC },
{ MEDIA_MIMETYPE_VIDEO_MPEG4, OMX_VIDEO_CodingMPEG4 },
{ MEDIA_MIMETYPE_VIDEO_H263, OMX_VIDEO_CodingH263 },
{ MEDIA_MIMETYPE_VIDEO_MPEG2, OMX_VIDEO_CodingMPEG2 },
diff --git a/media/libstagefright/MediaDefs.cpp b/media/libstagefright/MediaDefs.cpp
index c670bb4..8229e55 100644
--- a/media/libstagefright/MediaDefs.cpp
+++ b/media/libstagefright/MediaDefs.cpp
@@ -23,6 +23,7 @@ const char *MEDIA_MIMETYPE_IMAGE_JPEG = "image/jpeg";
const char *MEDIA_MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
const char *MEDIA_MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
const char *MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
+const char *MEDIA_MIMETYPE_VIDEO_HEVC = "video/hevc";
const char *MEDIA_MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
const char *MEDIA_MIMETYPE_VIDEO_H263 = "video/3gpp";
const char *MEDIA_MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 15b2bc0..786bf0d 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -35,7 +35,8 @@ LOCAL_C_INCLUDES := \
frameworks/av/services/medialog \
frameworks/av/services/audioflinger \
frameworks/av/services/audiopolicy \
- frameworks/av/services/camera/libcameraservice
+ frameworks/av/services/camera/libcameraservice \
+ $(call include-path-for, audio-utils)
LOCAL_MODULE:= mediaserver
LOCAL_32_BIT_ONLY := true
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index 9e2aa67..bd2541f 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -341,6 +341,13 @@ media_status_t AMediaCodec_releaseOutputBuffer(AMediaCodec *mData, size_t idx, b
}
EXPORT
+media_status_t AMediaCodec_releaseOutputBufferAtTime(
+ AMediaCodec *mData, size_t idx, int64_t timestampNs) {
+ ALOGV("render @ %lld", timestampNs);
+ return translate_error(mData->mCodec->renderOutputBufferAndRelease(idx, timestampNs));
+}
+
+EXPORT
media_status_t AMediaCodec_setNotificationCallback(AMediaCodec *mData, OnCodecEvent callback, void *userdata) {
mData->mCallback = callback;
mData->mCallbackUserData = userdata;
@@ -351,7 +358,7 @@ typedef struct AMediaCodecCryptoInfo {
int numsubsamples;
uint8_t key[16];
uint8_t iv[16];
- uint32_t mode;
+ cryptoinfo_mode_t mode;
size_t *clearbytes;
size_t *encryptedbytes;
} AMediaCodecCryptoInfo;
@@ -396,7 +403,7 @@ AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
int numsubsamples,
uint8_t key[16],
uint8_t iv[16],
- uint32_t mode,
+ cryptoinfo_mode_t mode,
size_t *clearbytes,
size_t *encryptedbytes) {
@@ -459,9 +466,9 @@ media_status_t AMediaCodecCryptoInfo_getIV(AMediaCodecCryptoInfo* ci, uint8_t *d
}
EXPORT
-uint32_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo* ci) {
+cryptoinfo_mode_t AMediaCodecCryptoInfo_getMode(AMediaCodecCryptoInfo* ci) {
if (!ci) {
- return AMEDIA_ERROR_INVALID_OBJECT;
+ return (cryptoinfo_mode_t) AMEDIA_ERROR_INVALID_OBJECT;
}
return ci->mode;
}
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index f982275..a0cbb70 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -101,7 +101,7 @@ void DrmListener::notify(DrmPlugin::EventType eventType, int extra, const Parcel
return;
}
- (*mListener)(mObj, sessionId, ndkEventType, extra, data, dataSize);
+ (*mListener)(mObj, &sessionId, ndkEventType, extra, data, dataSize);
delete [] sessionId.ptr;
delete [] data;
@@ -236,29 +236,35 @@ static bool findId(AMediaDrm *mObj, const AMediaDrmByteArray &id, List<idvec_t>:
}
EXPORT
-media_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId &sessionId) {
+media_status_t AMediaDrm_openSession(AMediaDrm *mObj, AMediaDrmSessionId *sessionId) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!sessionId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
Vector<uint8_t> session;
status_t status = mObj->mDrm->openSession(session);
if (status == OK) {
mObj->mIds.push_front(session);
List<idvec_t>::iterator iter = mObj->mIds.begin();
- sessionId.ptr = iter->array();
- sessionId.length = iter->size();
+ sessionId->ptr = iter->array();
+ sessionId->length = iter->size();
}
return AMEDIA_OK;
}
EXPORT
-media_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId) {
+media_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!sessionId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
List<idvec_t>::iterator iter;
- if (!findId(mObj, sessionId, iter)) {
+ if (!findId(mObj, *sessionId, iter)) {
return AMEDIA_DRM_SESSION_NOT_OPENED;
}
mObj->mDrm->closeSession(*iter);
@@ -267,20 +273,20 @@ media_status_t AMediaDrm_closeSession(AMediaDrm *mObj, const AMediaDrmSessionId
}
EXPORT
-media_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope &scope,
+media_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope *scope,
const uint8_t *init, size_t initSize, const char *mimeType, AMediaDrmKeyType keyType,
const AMediaDrmKeyValue *optionalParameters, size_t numOptionalParameters,
- const uint8_t *&keyRequest, size_t &keyRequestSize) {
+ const uint8_t **keyRequest, size_t *keyRequestSize) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
- if (!mimeType) {
+ if (!mimeType || !scope || !keyRequest || !keyRequestSize) {
return AMEDIA_ERROR_INVALID_PARAMETER;
}
List<idvec_t>::iterator iter;
- if (!findId(mObj, scope, iter)) {
+ if (!findId(mObj, *scope, iter)) {
return AMEDIA_DRM_SESSION_NOT_OPENED;
}
@@ -311,25 +317,25 @@ media_status_t AMediaDrm_getKeyRequest(AMediaDrm *mObj, const AMediaDrmScope &sc
if (status != OK) {
return translateStatus(status);
} else {
- keyRequest = mObj->mKeyRequest.array();
- keyRequestSize = mObj->mKeyRequest.size();
+ *keyRequest = mObj->mKeyRequest.array();
+ *keyRequestSize = mObj->mKeyRequest.size();
}
return AMEDIA_OK;
}
EXPORT
-media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope &scope,
- const uint8_t *response, size_t responseSize, AMediaDrmKeySetId &keySetId) {
+media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScope *scope,
+ const uint8_t *response, size_t responseSize, AMediaDrmKeySetId *keySetId) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
- if (!response || !responseSize) {
+ if (!scope || !response || !responseSize || !keySetId) {
return AMEDIA_ERROR_INVALID_PARAMETER;
}
List<idvec_t>::iterator iter;
- if (!findId(mObj, scope, iter)) {
+ if (!findId(mObj, *scope, iter)) {
return AMEDIA_DRM_SESSION_NOT_OPENED;
}
Vector<uint8_t> mdResponse;
@@ -340,41 +346,47 @@ media_status_t AMediaDrm_provideKeyResponse(AMediaDrm *mObj, const AMediaDrmScop
if (status == OK) {
mObj->mIds.push_front(mdKeySetId);
List<idvec_t>::iterator iter = mObj->mIds.begin();
- keySetId.ptr = iter->array();
- keySetId.length = iter->size();
+ keySetId->ptr = iter->array();
+ keySetId->length = iter->size();
} else {
- keySetId.ptr = NULL;
- keySetId.length = 0;
+ keySetId->ptr = NULL;
+ keySetId->length = 0;
}
return AMEDIA_OK;
}
EXPORT
-media_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId,
- const AMediaDrmKeySetId &keySetId) {
+media_status_t AMediaDrm_restoreKeys(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
+ const AMediaDrmKeySetId *keySetId) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!sessionId || !keySetId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
List<idvec_t>::iterator iter;
- if (!findId(mObj, sessionId, iter)) {
+ if (!findId(mObj, *sessionId, iter)) {
return AMEDIA_DRM_SESSION_NOT_OPENED;
}
Vector<uint8_t> keySet;
- keySet.appendArray(keySetId.ptr, keySetId.length);
+ keySet.appendArray(keySetId->ptr, keySetId->length);
return translateStatus(mObj->mDrm->restoreKeys(*iter, keySet));
}
EXPORT
-media_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId &keySetId) {
+media_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId *keySetId) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!keySetId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
List<idvec_t>::iterator iter;
status_t status;
- if (!findId(mObj, keySetId, iter)) {
+ if (!findId(mObj, *keySetId, iter)) {
Vector<uint8_t> keySet;
- keySet.appendArray(keySetId.ptr, keySetId.length);
+ keySet.appendArray(keySetId->ptr, keySetId->length);
status = mObj->mDrm->removeKeys(keySet);
} else {
status = mObj->mDrm->removeKeys(*iter);
@@ -384,25 +396,28 @@ media_status_t AMediaDrm_removeKeys(AMediaDrm *mObj, const AMediaDrmSessionId &k
}
EXPORT
-media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId,
- AMediaDrmKeyValue *keyValuePairs, size_t &numPairs) {
+media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
+ AMediaDrmKeyValue *keyValuePairs, size_t *numPairs) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!sessionId || !numPairs) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
List<idvec_t>::iterator iter;
- if (!findId(mObj, sessionId, iter)) {
+ if (!findId(mObj, *sessionId, iter)) {
return AMEDIA_DRM_SESSION_NOT_OPENED;
}
status_t status = mObj->mDrm->queryKeyStatus(*iter, mObj->mQueryResults);
if (status != OK) {
- numPairs = 0;
+ *numPairs = 0;
return translateStatus(status);
}
- if (mObj->mQueryResults.size() > numPairs) {
- numPairs = mObj->mQueryResults.size();
+ if (mObj->mQueryResults.size() > *numPairs) {
+ *numPairs = mObj->mQueryResults.size();
return AMEDIA_DRM_SHORT_BUFFER;
}
@@ -410,17 +425,17 @@ media_status_t AMediaDrm_queryKeyStatus(AMediaDrm *mObj, const AMediaDrmSessionI
keyValuePairs[i].mKey = mObj->mQueryResults.keyAt(i).string();
keyValuePairs[i].mValue = mObj->mQueryResults.keyAt(i).string();
}
- numPairs = mObj->mQueryResults.size();
+ *numPairs = mObj->mQueryResults.size();
return AMEDIA_OK;
}
EXPORT
-media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t *&provisionRequest,
- size_t &provisionRequestSize, const char *&serverUrl) {
+media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t **provisionRequest,
+ size_t *provisionRequestSize, const char **serverUrl) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
- if (!provisionRequestSize || !serverUrl) {
+ if (!provisionRequest || !provisionRequestSize || !*provisionRequestSize || !serverUrl) {
return AMEDIA_ERROR_INVALID_PARAMETER;
}
@@ -429,9 +444,9 @@ media_status_t AMediaDrm_getProvisionRequest(AMediaDrm *mObj, const uint8_t *&pr
if (status != OK) {
return translateStatus(status);
} else {
- provisionRequest = mObj->mProvisionRequest.array();
- provisionRequestSize = mObj->mProvisionRequest.size();
- serverUrl = mObj->mProvisionUrl.string();
+ *provisionRequest = mObj->mProvisionRequest.array();
+ *provisionRequestSize = mObj->mProvisionRequest.size();
+ *serverUrl = mObj->mProvisionUrl.string();
}
return AMEDIA_OK;
}
@@ -455,17 +470,20 @@ media_status_t AMediaDrm_provideProvisionResponse(AMediaDrm *mObj,
EXPORT
media_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj,
- AMediaDrmSecureStop *secureStops, size_t &numSecureStops) {
+ AMediaDrmSecureStop *secureStops, size_t *numSecureStops) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!numSecureStops) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
status_t status = mObj->mDrm->getSecureStops(mObj->mSecureStops);
if (status != OK) {
- numSecureStops = 0;
+ *numSecureStops = 0;
return translateStatus(status);
}
- if (numSecureStops < mObj->mSecureStops.size()) {
+ if (*numSecureStops < mObj->mSecureStops.size()) {
return AMEDIA_DRM_SHORT_BUFFER;
}
List<Vector<uint8_t> >::iterator iter = mObj->mSecureStops.begin();
@@ -476,59 +494,68 @@ media_status_t AMediaDrm_getSecureStops(AMediaDrm *mObj,
++iter;
++i;
}
- numSecureStops = mObj->mSecureStops.size();
+ *numSecureStops = mObj->mSecureStops.size();
return AMEDIA_OK;
}
EXPORT
media_status_t AMediaDrm_releaseSecureStops(AMediaDrm *mObj,
- const AMediaDrmSecureStop &ssRelease) {
+ const AMediaDrmSecureStop *ssRelease) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!ssRelease) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
Vector<uint8_t> release;
- release.appendArray(ssRelease.ptr, ssRelease.length);
+ release.appendArray(ssRelease->ptr, ssRelease->length);
return translateStatus(mObj->mDrm->releaseSecureStops(release));
}
EXPORT
media_status_t AMediaDrm_getPropertyString(AMediaDrm *mObj, const char *propertyName,
- const char *&propertyValue) {
+ const char **propertyValue) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!propertyName || !propertyValue) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
status_t status = mObj->mDrm->getPropertyString(String8(propertyName),
mObj->mPropertyString);
if (status == OK) {
- propertyValue = mObj->mPropertyString.string();
+ *propertyValue = mObj->mPropertyString.string();
} else {
- propertyValue = NULL;
+ *propertyValue = NULL;
}
return translateStatus(status);
}
EXPORT
media_status_t AMediaDrm_getPropertyByteArray(AMediaDrm *mObj,
- const char *propertyName, AMediaDrmByteArray &propertyValue) {
+ const char *propertyName, AMediaDrmByteArray *propertyValue) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!propertyName || !propertyValue) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
status_t status = mObj->mDrm->getPropertyByteArray(String8(propertyName),
mObj->mPropertyByteArray);
if (status == OK) {
- propertyValue.ptr = mObj->mPropertyByteArray.array();
- propertyValue.length = mObj->mPropertyByteArray.size();
+ propertyValue->ptr = mObj->mPropertyByteArray.array();
+ propertyValue->length = mObj->mPropertyByteArray.size();
} else {
- propertyValue.ptr = NULL;
- propertyValue.length = 0;
+ propertyValue->ptr = NULL;
+ propertyValue->length = 0;
}
return translateStatus(status);
}
@@ -598,31 +625,40 @@ static media_status_t encrypt_decrypt_common(AMediaDrm *mObj,
}
EXPORT
-media_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_encrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
const uint8_t *input, uint8_t *output, size_t dataSize) {
- return encrypt_decrypt_common(mObj, sessionId, cipherAlgorithm, keyId, iv,
+ if (!sessionId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
+ return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
input, output, dataSize, true);
}
EXPORT
-media_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_decrypt(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
const char *cipherAlgorithm, uint8_t *keyId, uint8_t *iv,
const uint8_t *input, uint8_t *output, size_t dataSize) {
- return encrypt_decrypt_common(mObj, sessionId, cipherAlgorithm, keyId, iv,
+ if (!sessionId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
+ return encrypt_decrypt_common(mObj, *sessionId, cipherAlgorithm, keyId, iv,
input, output, dataSize, false);
}
EXPORT
-media_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
const char *macAlgorithm, uint8_t *keyId, uint8_t *message, size_t messageSize,
uint8_t *signature, size_t *signatureSize) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!sessionId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
List<idvec_t>::iterator iter;
- if (!findId(mObj, sessionId, iter)) {
+ if (!findId(mObj, *sessionId, iter)) {
return AMEDIA_DRM_SESSION_NOT_OPENED;
}
@@ -650,15 +686,18 @@ media_status_t AMediaDrm_sign(AMediaDrm *mObj, const AMediaDrmSessionId &session
}
EXPORT
-media_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId &sessionId,
+media_status_t AMediaDrm_verify(AMediaDrm *mObj, const AMediaDrmSessionId *sessionId,
const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
const uint8_t *signature, size_t signatureSize) {
if (!mObj || mObj->mDrm == NULL) {
return AMEDIA_ERROR_INVALID_OBJECT;
}
+ if (!sessionId) {
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
List<idvec_t>::iterator iter;
- if (!findId(mObj, sessionId, iter)) {
+ if (!findId(mObj, *sessionId, iter)) {
return AMEDIA_DRM_SESSION_NOT_OPENED;
}
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index 563358f..b0a9590 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -150,6 +150,20 @@ bool AMediaExtractor_advance(AMediaExtractor *mData) {
}
EXPORT
+media_status_t AMediaExtractor_seekTo(AMediaExtractor *ex, int64_t seekPosUs, SeekMode mode) {
+ android::MediaSource::ReadOptions::SeekMode sfmode;
+ if (mode == AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC) {
+ sfmode = android::MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC;
+ } else if (mode == AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC) {
+ sfmode = android::MediaSource::ReadOptions::SEEK_CLOSEST_SYNC;
+ } else {
+ sfmode = android::MediaSource::ReadOptions::SEEK_NEXT_SYNC;
+ }
+
+ return translate_error(ex->mImpl->seekTo(seekPosUs, sfmode));
+}
+
+EXPORT
ssize_t AMediaExtractor_readSampleData(AMediaExtractor *mData, uint8_t *buffer, size_t capacity) {
//ALOGV("readSampleData");
sp<ABuffer> tmp = new ABuffer(buffer, capacity);
@@ -331,7 +345,7 @@ AMediaCodecCryptoInfo *AMediaExtractor_getSampleCryptoInfo(AMediaExtractor *ex)
numSubSamples,
(uint8_t*) key,
(uint8_t*) iv,
- mode,
+ (cryptoinfo_mode_t) mode,
(size_t*) cleardata,
(size_t*) crypteddata);
}
diff --git a/media/ndk/NdkMediaMuxer.cpp b/media/ndk/NdkMediaMuxer.cpp
index 19b9fc4..50fc336 100644
--- a/media/ndk/NdkMediaMuxer.cpp
+++ b/media/ndk/NdkMediaMuxer.cpp
@@ -96,10 +96,10 @@ media_status_t AMediaMuxer_stop(AMediaMuxer *muxer) {
EXPORT
media_status_t AMediaMuxer_writeSampleData(AMediaMuxer *muxer,
- size_t trackIdx, const uint8_t *data, const AMediaCodecBufferInfo &info) {
- sp<ABuffer> buf = new ABuffer((void*)(data + info.offset), info.size);
+ size_t trackIdx, const uint8_t *data, const AMediaCodecBufferInfo *info) {
+ sp<ABuffer> buf = new ABuffer((void*)(data + info->offset), info->size);
return translate_error(
- muxer->mImpl->writeSampleData(buf, trackIdx, info.presentationTimeUs, info.flags));
+ muxer->mImpl->writeSampleData(buf, trackIdx, info->presentationTimeUs, info->flags));
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 11170c2..45e17f8 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1837,7 +1837,8 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
if (status == BAD_VALUE &&
reqFormat == config.format && config.format == AUDIO_FORMAT_PCM_16_BIT &&
(config.sample_rate <= 2 * reqSamplingRate) &&
- (popcount(config.channel_mask) <= FCC_2) && (popcount(reqChannelMask) <= FCC_2)) {
+ (audio_channel_count_from_in_mask(config.channel_mask) <= FCC_2) &&
+ (audio_channel_count_from_in_mask(reqChannelMask) <= FCC_2)) {
// FIXME describe the change proposed by HAL (save old values so we can log them here)
ALOGV("openInput() reopening with proposed sampling rate and channel mask");
inStream = NULL;
@@ -1857,7 +1858,8 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
TEE_SINK_OLD, // copy input using an existing pipe
} kind;
NBAIO_Format format = Format_from_SR_C(inStream->common.get_sample_rate(&inStream->common),
- popcount(inStream->common.get_channels(&inStream->common)));
+ audio_channel_count_from_in_mask(
+ inStream->common.get_channels(&inStream->common)));
if (!mTeeSinkInputEnabled) {
kind = TEE_SINK_NO;
} else if (!Format_isValid(format)) {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index d69d6a2..d2ded9a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -82,9 +82,6 @@ class ServerProxy;
static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
-#define MAX_GAIN 4096.0f
-#define MAX_GAIN_INT 0x1000
-
#define INCLUDING_FROM_AUDIOFLINGER_H
class AudioFlinger :
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index 2d67efb..805eaa4 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -159,7 +159,6 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
if (names != 0) {
int n = __builtin_ctz(names);
ALOGV("add track (%d)", n);
- mTrackNames |= 1 << n;
// assume default parameters for the track, except where noted below
track_t* t = &mState.tracks[n];
t->needs = 0;
@@ -175,10 +174,10 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
// no initialization needed
// t->prevAuxLevel
// t->frameCount
- t->channelCount = 2;
+ t->channelCount = audio_channel_count_from_out_mask(channelMask);
t->enabled = false;
t->format = 16;
- t->channelMask = AUDIO_CHANNEL_OUT_STEREO;
+ t->channelMask = channelMask;
t->sessionId = sessionId;
// setBufferProvider(name, AudioBufferProvider *) is required before enable(name)
t->bufferProvider = NULL;
@@ -196,12 +195,14 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId)
t->mMixerFormat = AUDIO_FORMAT_PCM_16_BIT;
status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask);
- if (status == OK) {
- return TRACK0 + n;
+ if (status != OK) {
+ ALOGE("AudioMixer::getTrackName invalid channelMask (%#x)", channelMask);
+ return -1;
}
- ALOGE("AudioMixer::getTrackName(0x%x) failed, error preparing track for downmix",
- channelMask);
+ mTrackNames |= 1 << n;
+ return TRACK0 + n;
}
+ ALOGE("AudioMixer::getTrackName out of available tracks");
return -1;
}
@@ -215,7 +216,7 @@ void AudioMixer::invalidateState(uint32_t mask)
status_t AudioMixer::initTrackDownmix(track_t* pTrack, int trackNum, audio_channel_mask_t mask)
{
- uint32_t channelCount = popcount(mask);
+ uint32_t channelCount = audio_channel_count_from_out_mask(mask);
ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
status_t status = OK;
if (channelCount > MAX_NUM_CHANNELS) {
@@ -410,7 +411,7 @@ void AudioMixer::setParameter(int name, int target, int param, void *value)
audio_channel_mask_t mask =
static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
if (track.channelMask != mask) {
- uint32_t channelCount = popcount(mask);
+ uint32_t channelCount = audio_channel_count_from_out_mask(mask);
ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
track.channelMask = mask;
track.channelCount = channelCount;
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index e5e120c..09e63a6 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -30,6 +30,9 @@
#include <system/audio.h>
#include <media/nbaio/NBLog.h>
+// FIXME This is actually unity gain, which might not be max in future, expressed in U.12
+#define MAX_GAIN_INT AudioMixer::UNITY_GAIN
+
namespace android {
// ----------------------------------------------------------------------------
@@ -91,6 +94,7 @@ public:
REMOVE = 0x4102, // Remove the sample rate converter on this track name;
// the track is restored to the mix sample rate.
// for target RAMP_VOLUME and VOLUME (8 channels max)
+ // FIXME use float for these 3 to improve the dynamic range
VOLUME0 = 0x4200,
VOLUME1 = 0x4201,
AUXLEVEL = 0x4210,
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index ccc4825..4170fd4 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -270,6 +270,7 @@ public:
sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
sp<EffectModule> getEffectFromId_l(int id);
sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
+ // FIXME use float to improve the dynamic range
bool setVolume_l(uint32_t *left, uint32_t *right);
void setDevice_l(audio_devices_t device);
void setMode_l(audio_mode_t mode);
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 5cb42cc..1caed11 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -224,17 +224,13 @@ void FastMixer::onStateChange()
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1);
if (mixer != NULL) {
- // calling getTrackName with default channel mask and a random invalid
- // sessionId (no effects here)
- name = mixer->getTrackName(AUDIO_CHANNEL_OUT_STEREO, -555);
+ name = mixer->getTrackName(fastTrack->mChannelMask, AUDIO_SESSION_OUTPUT_MIX);
ALOG_ASSERT(name >= 0);
fastTrackNames[i] = name;
mixer->setBufferProvider(name, bufferProvider);
mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
(void *) mixBuffer);
// newly allocated track names default to full scale volume
- mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
- (void *)(uintptr_t)fastTrack->mChannelMask);
mixer->enable(name);
}
generations[i] = fastTrack->mGeneration;
@@ -257,9 +253,9 @@ void FastMixer::onStateChange()
mixer->setBufferProvider(name, bufferProvider);
if (fastTrack->mVolumeProvider == NULL) {
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0,
- (void *)0x1000);
+ (void *) MAX_GAIN_INT);
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1,
- (void *)0x1000);
+ (void *) MAX_GAIN_INT);
}
mixer->setParameter(name, AudioMixer::RESAMPLE,
AudioMixer::REMOVE, NULL);
@@ -312,11 +308,13 @@ void FastMixer::onWork()
int name = fastTrackNames[i];
ALOG_ASSERT(name >= 0);
if (fastTrack->mVolumeProvider != NULL) {
- uint32_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
+ gain_minifloat_packed_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0,
- (void *)(uintptr_t)(vlr & 0xFFFF));
+ (void *) (uintptr_t)
+ (float_from_gain(gain_minifloat_unpack_left(vlr)) * MAX_GAIN_INT));
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1,
- (void *)(uintptr_t)(vlr >> 16));
+ (void *) (uintptr_t)
+ (float_from_gain(gain_minifloat_unpack_right(vlr)) * MAX_GAIN_INT));
}
// FIXME The current implementation of framesReady() for fast tracks
// takes a tryLock, which can block
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index be1a376..e388fb3 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_AUDIO_FAST_MIXER_STATE_H
#define ANDROID_AUDIO_FAST_MIXER_STATE_H
+#include <audio_utils/minifloat.h>
#include <system/audio.h>
#include <media/ExtendedAudioBufferProvider.h>
#include <media/nbaio/NBAIO.h>
@@ -29,9 +30,8 @@ struct FastMixerDumpState;
class VolumeProvider {
public:
- // Return the track volume in U4_12 format: left in lower half, right in upper half. The
- // provider implementation is responsible for validating that the return value is in range.
- virtual uint32_t getVolumeLR() = 0;
+ // The provider implementation is responsible for validating that the return value is in range.
+ virtual gain_minifloat_packed_t getVolumeLR() = 0;
protected:
VolumeProvider() { }
virtual ~VolumeProvider() { }
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 08b1728..6f1f293 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -65,7 +65,7 @@ public:
void signal();
// implement FastMixerState::VolumeProvider interface
- virtual uint32_t getVolumeLR();
+ virtual gain_minifloat_packed_t getVolumeLR();
virtual status_t setSyncEvent(const sp<SyncEvent>& event);
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 2d4e025..ce08ff1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -35,6 +35,7 @@
#include <audio_effects/effect_aec.h>
#include <audio_utils/primitives.h>
#include <audio_utils/format.h>
+#include <audio_utils/minifloat.h>
// NBAIO implementations
#include <media/nbaio/AudioStreamOutSink.h>
@@ -1730,7 +1731,7 @@ void AudioFlinger::PlaybackThread::readOutputParameters_l()
LOG_ALWAYS_FATAL("HAL channel mask %#x not supported for mixed output; "
"must be AUDIO_CHANNEL_OUT_STEREO", mChannelMask);
}
- mChannelCount = popcount(mChannelMask);
+ mChannelCount = audio_channel_count_from_out_mask(mChannelMask);
mFormat = mOutput->stream->common.get_format(&mOutput->stream->common);
if (!audio_is_valid_format(mFormat)) {
LOG_ALWAYS_FATAL("HAL format %#x not valid for output", mFormat);
@@ -3255,21 +3256,23 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
float typeVolume = mStreamTypes[track->streamType()].volume;
float v = masterVolume * typeVolume;
AudioTrackServerProxy *proxy = track->mAudioTrackServerProxy;
- uint32_t vlr = proxy->getVolumeLR();
- vl = vlr & 0xFFFF;
- vr = vlr >> 16;
+ gain_minifloat_packed_t vlr = proxy->getVolumeLR();
+ float vlf = float_from_gain(gain_minifloat_unpack_left(vlr));
+ float vrf = float_from_gain(gain_minifloat_unpack_right(vlr));
// track volumes come from shared memory, so can't be trusted and must be clamped
- if (vl > MAX_GAIN_INT) {
- ALOGV("Track left volume out of range: %04X", vl);
- vl = MAX_GAIN_INT;
+ if (vlf > GAIN_FLOAT_UNITY) {
+ ALOGV("Track left volume out of range: %.3g", vlf);
+ vlf = GAIN_FLOAT_UNITY;
}
- if (vr > MAX_GAIN_INT) {
- ALOGV("Track right volume out of range: %04X", vr);
- vr = MAX_GAIN_INT;
+ if (vrf > GAIN_FLOAT_UNITY) {
+ ALOGV("Track right volume out of range: %.3g", vrf);
+ vrf = GAIN_FLOAT_UNITY;
}
// now apply the master volume and stream type volume
- vl = (uint32_t)(v * vl) << 12;
- vr = (uint32_t)(v * vr) << 12;
+ // FIXME we're losing the wonderful dynamic range in the minifloat representation
+ float v8_24 = v * (MAX_GAIN_INT * MAX_GAIN_INT);
+ vl = (uint32_t) (v8_24 * vlf);
+ vr = (uint32_t) (v8_24 * vrf);
// assuming master volume and stream type volume each go up to 1.0,
// vl and vr are now in 8.24 format
@@ -3296,6 +3299,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
track->mHasVolumeController = false;
}
+ // FIXME Use float
// Convert volumes from 8.24 to 4.12 format
// This additional clamping is needed in case chain->setVolume_l() overshot
vl = (vl + (1 << 11)) >> 12;
@@ -3750,13 +3754,17 @@ void AudioFlinger::DirectOutputThread::processVolume_l(Track *track, bool lastTr
float typeVolume = mStreamTypes[track->streamType()].volume;
float v = mMasterVolume * typeVolume;
AudioTrackServerProxy *proxy = track->mAudioTrackServerProxy;
- uint32_t vlr = proxy->getVolumeLR();
- float v_clamped = v * (vlr & 0xFFFF);
- if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
- left = v_clamped/MAX_GAIN;
- v_clamped = v * (vlr >> 16);
- if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
- right = v_clamped/MAX_GAIN;
+ gain_minifloat_packed_t vlr = proxy->getVolumeLR();
+ left = float_from_gain(gain_minifloat_unpack_left(vlr));
+ if (left > GAIN_FLOAT_UNITY) {
+ left = GAIN_FLOAT_UNITY;
+ }
+ left *= v;
+ right = float_from_gain(gain_minifloat_unpack_right(vlr));
+ if (right > GAIN_FLOAT_UNITY) {
+ right = GAIN_FLOAT_UNITY;
+ }
+ right *= v;
}
if (lastTrack) {
@@ -4152,7 +4160,10 @@ void AudioFlinger::OffloadThread::threadLoop_exit()
mMixerStatus = MIXER_DRAIN_ALL;
threadLoop_drain();
}
- mCallbackThread->exit();
+ if (mUseAsyncWrite) {
+ ALOG_ASSERT(mCallbackThread != 0);
+ mCallbackThread->exit();
+ }
PlaybackThread::threadLoop_exit();
}
@@ -5564,8 +5575,8 @@ bool AudioFlinger::RecordThread::checkForNewParameter_l(const String8& keyValueP
reqFormat == AUDIO_FORMAT_PCM_16_BIT &&
(mInput->stream->common.get_sample_rate(&mInput->stream->common)
<= (2 * samplingRate)) &&
- popcount(mInput->stream->common.get_channels(&mInput->stream->common))
- <= FCC_2 &&
+ audio_channel_count_from_in_mask(
+ mInput->stream->common.get_channels(&mInput->stream->common)) <= FCC_2 &&
(channelMask == AUDIO_CHANNEL_IN_MONO ||
channelMask == AUDIO_CHANNEL_IN_STEREO)) {
status = NO_ERROR;
@@ -5619,7 +5630,7 @@ void AudioFlinger::RecordThread::readInputParameters_l()
{
mSampleRate = mInput->stream->common.get_sample_rate(&mInput->stream->common);
mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common);
- mChannelCount = popcount(mChannelMask);
+ mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
mFormat = mInput->stream->common.get_format(&mInput->stream->common);
if (mFormat != AUDIO_FORMAT_PCM_16_BIT) {
ALOGE("HAL format %#x not supported; must be AUDIO_FORMAT_PCM_16_BIT", mFormat);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 6dc7f30..de1782d 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -34,6 +34,7 @@
#include <media/nbaio/Pipe.h>
#include <media/nbaio/PipeReader.h>
+#include <audio_utils/minifloat.h>
// ----------------------------------------------------------------------------
@@ -81,7 +82,9 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase(
mSampleRate(sampleRate),
mFormat(format),
mChannelMask(channelMask),
- mChannelCount(popcount(channelMask)),
+ mChannelCount(isOut ?
+ audio_channel_count_from_out_mask(channelMask) :
+ audio_channel_count_from_in_mask(channelMask)),
mFrameSize(audio_is_linear_pcm(format) ?
mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
mFrameCount(frameCount),
@@ -459,7 +462,7 @@ void AudioFlinger::PlaybackThread::Track::destroy()
void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size, bool active)
{
- uint32_t vlr = mAudioTrackServerProxy->getVolumeLR();
+ gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
if (isFastTrack()) {
sprintf(buffer, " F %2d", mFastIndex);
} else if (mName >= AudioMixer::TRACK0) {
@@ -532,8 +535,8 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size, bool a
stateChar,
mFillingUpStatus,
mAudioTrackServerProxy->getSampleRate(),
- 20.0 * log10((vlr & 0xFFFF) / 4096.0),
- 20.0 * log10((vlr >> 16) / 4096.0),
+ 20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
+ 20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
mCblk->mServer,
mMainBuffer,
mAuxBuffer,
@@ -959,27 +962,27 @@ void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_
// implement VolumeBufferProvider interface
-uint32_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
+gain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
{
// called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
- uint32_t vlr = mAudioTrackServerProxy->getVolumeLR();
- uint32_t vl = vlr & 0xFFFF;
- uint32_t vr = vlr >> 16;
+ gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
+ float vl = float_from_gain(gain_minifloat_unpack_left(vlr));
+ float vr = float_from_gain(gain_minifloat_unpack_right(vlr));
// track volumes come from shared memory, so can't be trusted and must be clamped
- if (vl > MAX_GAIN_INT) {
- vl = MAX_GAIN_INT;
+ if (vl > GAIN_FLOAT_UNITY) {
+ vl = GAIN_FLOAT_UNITY;
}
- if (vr > MAX_GAIN_INT) {
- vr = MAX_GAIN_INT;
+ if (vr > GAIN_FLOAT_UNITY) {
+ vr = GAIN_FLOAT_UNITY;
}
// now apply the cached master volume and stream type volume;
// this is trusted but lacks any synchronization or barrier so may be stale
float v = mCachedVolume;
vl *= v;
vr *= v;
- // re-combine into U4.16
- vlr = (vr << 16) | (vl & 0xFFFF);
+ // re-combine into packed minifloat
+ vlr = gain_minifloat_pack(gain_from_float(vl), gain_from_float(vr));
// FIXME look at mute, pause, and stop flags
return vlr;
}
@@ -1590,7 +1593,7 @@ AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
// since client and server are in the same process,
// the buffer has the same virtual address on both sides
mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize);
- mClientProxy->setVolumeLR((uint32_t(uint16_t(0x1000)) << 16) | uint16_t(0x1000));
+ mClientProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY);
mClientProxy->setSendLevel(0.0);
mClientProxy->setSampleRate(sampleRate);
mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize,
@@ -1849,7 +1852,7 @@ AudioFlinger::RecordThread::RecordTrack::RecordTrack(
mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount, mFrameSize);
- uint32_t channelCount = popcount(channelMask);
+ uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
// FIXME I don't understand either of the channel count checks
if (thread->mSampleRate != sampleRate && thread->mChannelCount <= FCC_2 &&
channelCount <= FCC_2) {
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 62a44ee..bd9b15a 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -70,24 +70,36 @@ const StringToEnum sDeviceNameToEnumTable[] = {
STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL),
+ STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
+ STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX),
+ STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE),
+ STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
+ STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
+ STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI),
STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
};
const StringToEnum sFlagNameToEnumTable[] = {