diff options
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[] = { |