From 74da109102864f19b3dcdb30cd1d92c46fb12f2f Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 7 Nov 2012 16:02:13 -0800 Subject: Support Wifi display devices that rename themselves. Some Wifi display devices like to rename themselves after a connection completes (or at other times). Make sure to update the name of the display when we detect that it changed in our scan results. This problem is somewhat complicated by the fact that we remember the display name persistently, so we need to update our list of remembered displays too. Improve the state machine to avoid redundant attempts to disconnect or cancel connection. Bug: 7478895 Change-Id: I35a9e2c6a8deadbe892dacd5e3b4a5a2b12d6cf0 --- media/java/android/media/MediaRouter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'media/java') diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 2a5a16e..8701f36 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -862,7 +862,7 @@ public class MediaRouter { private static WifiDisplay findMatchingDisplay(WifiDisplay d, WifiDisplay[] displays) { for (int i = 0; i < displays.length; i++) { final WifiDisplay other = displays[i]; - if (d.getDeviceAddress().equals(other.getDeviceAddress())) { + if (d.hasSameAddress(other)) { return other; } } -- cgit v1.1 From cd3231f501b7ee038af5ab378ee5550090b7bc2e Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 2 Nov 2012 16:48:26 -0700 Subject: audio service fix dock after crash - DO NOT MERGE merge from master: "audio service: set dock use on mediaserver restart Restore forced usage of dock audio for media according to current setting when media server restarts." Bug 7485250. Change-Id: Ie67b80ede1ed92d223dd96de83c1beb985dfba06 --- media/java/android/media/AudioService.java | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'media/java') diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 315196e..87ece50 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -3324,6 +3324,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished { mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP); } + + synchronized (mSettingsLock) { + AudioSystem.setForceUse(AudioSystem.FOR_DOCK, + mDockAudioMediaEnabled ? + AudioSystem.FORCE_ANALOG_DOCK : AudioSystem.FORCE_NONE); + } + // indicate the end of reconfiguration phase to audio HAL AudioSystem.setParameters("restarting=false"); break; -- cgit v1.1 From 0214f2b8560928d3160a938f3edde4d3aa03c6c5 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Mon, 5 Nov 2012 14:54:12 -0800 Subject: AudioService: undock audio glitch - DO NOT MERGE merge from master: "AudioService: improve low end dock audio control Low end docks have a menu to enable use of audio for media: automatically enabling/disabling use of audio when the dock is connected/disconnected is useless and can be the source of audio glitches. Bug 7463620." Change-Id: I3b7e7ebe660bb3f0e4367d2a3ed63ee76f78fe58 --- media/java/android/media/AudioService.java | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'media/java') diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 87ece50..22f699f 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -436,6 +436,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private boolean mDockAudioMediaEnabled = true; + private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; + /////////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////////// @@ -3758,13 +3760,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { config = AudioSystem.FORCE_BT_CAR_DOCK; break; case Intent.EXTRA_DOCK_STATE_LE_DESK: - synchronized (mSettingsLock) { - if (mDockAudioMediaEnabled) { - config = AudioSystem.FORCE_ANALOG_DOCK; - } else { - config = AudioSystem.FORCE_NONE; - } - } + config = AudioSystem.FORCE_ANALOG_DOCK; break; case Intent.EXTRA_DOCK_STATE_HE_DESK: config = AudioSystem.FORCE_DIGITAL_DOCK; @@ -3773,8 +3769,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { default: config = AudioSystem.FORCE_NONE; } - - AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); + // Low end docks have a menu to enable or disable audio + // (see mDockAudioMediaEnabled) + if (!((dockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || + ((dockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) && + (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK)))) { + AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config); + } + mDockState = dockState; } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) { state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_DISCONNECTED); -- cgit v1.1 From 99a86d06333b0ff668f6c0d0294d1f72c7a40d8e Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 14 Nov 2012 09:16:59 -0800 Subject: Clarify that MediaFormat.KEY_IS_ADTS only applies to decoding AAC audio content and cannot be used to configure the _encoder_ to emit ADTS content. Change-Id: I47177099b204027b726b2c7ec9b93be6835d88f6 related-to-bug: 7542186 --- media/java/android/media/MediaFormat.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'media/java') diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 4414191..169502b 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -50,7 +50,7 @@ import java.util.Map; * NameValue TypeDescription * {@link #KEY_CHANNEL_COUNT}Integer * {@link #KEY_SAMPLE_RATE}Integer - * {@link #KEY_IS_ADTS}Integeroptional, if content is AAC audio, setting this key to 1 indicates that each audio frame is prefixed by the ADTS header. + * {@link #KEY_IS_ADTS}Integeroptional, if decoding AAC audio content, setting this key to 1 indicates that each audio frame is prefixed by the ADTS header. * {@link #KEY_AAC_PROFILE}Integerencoder-only, optional, if content is AAC audio, specifies the desired profile. * {@link #KEY_CHANNEL_MASK}IntegerA mask of audio channel assignments * {@link #KEY_FLAC_COMPRESSION_LEVEL}Integerencoder-only, optional, if content is FLAC audio, specifies the desired compression level. @@ -140,6 +140,8 @@ public final class MediaFormat { * A key mapping to a value of 1 if the content is AAC audio and * audio frames are prefixed with an ADTS header. * The associated value is an integer (0 or 1). + * This key is only supported when _decoding_ content, it cannot + * be used to configure an encoder to emit ADTS output. */ public static final String KEY_IS_ADTS = "is-adts"; -- cgit v1.1 From 4dd3fb3e2c2b0d3dd7cb18f9e7e40a7b9dee8692 Mon Sep 17 00:00:00 2001 From: Jean-Michel Trivi Date: Tue, 20 Nov 2012 17:06:51 -0800 Subject: Fix audio focus evaluation order for display update Change 1f9196a8e5de9b004e61afabc70b18caf7cf9c7e introduced an issue when trying to ignore audio focus entries in the stack that don't use the music stream, or are for transient audio focus gain, for remote control display updates. The bug was that the audio focus stack traversal was not starting from the top, as it should. It was using the iterator order, which, in the case of a stack, starts with the bottom-most entry. The fix consists in traversing the stack from the top, i.e. from the last element of the vector used to hold the stack entries. Bug 7311023 Change-Id: I0c1900dbf98599a621a420ab55531a3eee838fe5 --- media/java/android/media/AudioService.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'media/java') diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 22f699f..56abed4 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -5088,18 +5088,23 @@ public class AudioService extends IAudioService.Stub implements OnFinished { // top of the stack for the media button event receivers : simply using the top of the // stack would make the entry disappear from the RemoteControlDisplay in conditions such as // notifications playing during music playback. - // crawl the AudioFocus stack until an entry is found with the following characteristics: + // Crawl the AudioFocus stack from the top until an entry is found with the following + // characteristics: // - focus gain on STREAM_MUSIC stream // - non-transient focus gain on a stream other than music FocusStackEntry af = null; - Iterator stackIterator = mFocusStack.iterator(); - while(stackIterator.hasNext()) { - FocusStackEntry fse = (FocusStackEntry)stackIterator.next(); - if ((fse.mStreamType == AudioManager.STREAM_MUSIC) - || (fse.mFocusChangeType == AudioManager.AUDIOFOCUS_GAIN)) { - af = fse; - break; + try { + for (int index = mFocusStack.size()-1; index >= 0; index--) { + FocusStackEntry fse = mFocusStack.elementAt(index); + if ((fse.mStreamType == AudioManager.STREAM_MUSIC) + || (fse.mFocusChangeType == AudioManager.AUDIOFOCUS_GAIN)) { + af = fse; + break; + } } + } catch (ArrayIndexOutOfBoundsException e) { + Log.e(TAG, "Wrong index accessing audio focus stack when updating RCD: " + e); + af = null; } if (af == null) { clearRemoteControlDisplay_syncAfRcs(); @@ -5120,6 +5125,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { clearRemoteControlDisplay_syncAfRcs(); return; } + // refresh conditions were verified: update the remote controls // ok to call: synchronized mAudioFocusLock then on mRCStack, mRCStack is not empty updateRemoteControlDisplay_syncAfRcs(infoChangedFlags); -- cgit v1.1 From 1cf2ca83584a4cf0aa3ded787bd191b9a60e3521 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Wed, 28 Nov 2012 10:46:56 -0800 Subject: Clean up behavior of type arguments for MediaRouter#getSelectedRoute MediaRouter's policy so far has been around a single selected route, but when route types are entirely orthogonal this should not be the case. However we still don't want to get into a situation where we have multiple, very different routes selected for different types at the same time, we still want to have more of an element of predictability. Behavior of getSelectedRoute is now: * If the selected route matches at least one type with the requested type flags, it is still considered selected for that request. * If the caller specifically requested the selected user route and the currently selected route is not a user route, return null. * If the requested type flags do not match any types with the selected route, return the default system route. Note that this is "any" behavior instead of "all" - this matches existing usage of the method. We may consider adding an "all" variant later on. Bug 7588042 Change-Id: I3a79d8153ca6b882fd3ef6b9b1de8f538873dec2 --- media/java/android/media/MediaRouter.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'media/java') diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index 8701f36..8b489b1 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -313,13 +313,25 @@ public class MediaRouter { } /** - * Return the currently selected route for the given types + * Return the currently selected route for any of the given types * * @param type route types * @return the selected route */ public RouteInfo getSelectedRoute(int type) { - return sStatic.mSelectedRoute; + if (sStatic.mSelectedRoute != null && + (sStatic.mSelectedRoute.mSupportedTypes & type) != 0) { + // If the selected route supports any of the types supplied, it's still considered + // 'selected' for that type. + return sStatic.mSelectedRoute; + } else if (type == ROUTE_TYPE_USER) { + // The caller specifically asked for a user route and the currently selected route + // doesn't qualify. + return null; + } + // If the above didn't match and we're not specifically asking for a user route, + // consider the default selected. + return sStatic.mDefaultAudioVideo; } /** -- cgit v1.1 From 05274f348e12983eb8613cc6eb9ae561e8197e28 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Thu, 29 Nov 2012 12:48:18 -0800 Subject: AudioService: improve initial safe volume delay AudioService relies on a valid mmc in order to enforce the headset volume limitation or not. There is a timeout to enforce the limitation if no mcc is configured after boot. Until this timeout is reached or a valid SIM is detected the headset volume is not limited. This change makes that the last known volume limitation state (enforced or not) is persisted so that next time we boot, last known state is applied until a new mcc is configured if any. In most cases, the mcc does not change from one boot to the next and we do the right thing. If teh mcc does change, the correct policy will be enforced when the mcc is detected or after the timeout. Also fix a bug where the volume panel was not displayed if the limitation mechanism is triggered at the first press on VOL+ key. Bug 7455275. Change-Id: Id0f2996d893d38c6a14f4f9e4a0e9e3be17ef127 --- media/java/android/media/AudioService.java | 158 ++++++++++++++++++----------- 1 file changed, 97 insertions(+), 61 deletions(-) (limited to 'media/java') diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 22f699f..96c955f 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -157,6 +157,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished { private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 25; private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME = 26; private static final int MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED = 27; + private static final int MSG_PERSIST_SAFE_VOLUME_STATE = 28; // flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be // persisted @@ -481,6 +482,14 @@ public class AudioService extends IAudioService.Stub implements OnFinished { null, 0); + mSafeMediaVolumeState = new Integer(Settings.Global.getInt(mContentResolver, + Settings.Global.AUDIO_SAFE_VOLUME_STATE, + SAFE_MEDIA_VOLUME_NOT_CONFIGURED)); + // The default safe volume index read here will be replaced by the actual value when + // the mcc is read by onConfigureSafeVolume() + mSafeMediaVolumeIndex = mContext.getResources().getInteger( + com.android.internal.R.integer.config_safe_media_volume_index) * 10; + readPersistedSettings(); mSettingsObserver = new SettingsObserver(); updateStreamVolumeAlias(false /*updateVolumes*/); @@ -488,8 +497,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished { mMediaServerOk = true; - mSafeMediaVolumeState = new Integer(SAFE_MEDIA_VOLUME_NOT_CONFIGURED); - // Call setRingerModeInt() to apply correct mute // state on streams affected by ringer mode. mRingerModeMutedStreams = 0; @@ -822,70 +829,72 @@ public class AudioService extends IAudioService.Stub implements OnFinished { // convert one UI step (+/-1) into a number of internal units on the stream alias int step = rescaleIndex(10, streamType, streamTypeAlias); - if ((direction == AudioManager.ADJUST_RAISE) && - !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { - return; - } - int index; int oldIndex; - flags &= ~AudioManager.FLAG_FIXED_VOLUME; - if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && - ((device & mFixedVolumeDevices) != 0)) { - flags |= AudioManager.FLAG_FIXED_VOLUME; - index = mStreamStates[streamType].getMaxIndex(); + if ((direction == AudioManager.ADJUST_RAISE) && + !checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) { + index = mStreamStates[streamType].getIndex(device, + (streamState.muteCount() != 0) /* lastAudible */); oldIndex = index; } else { - // If either the client forces allowing ringer modes for this adjustment, - // or the stream type is one that is affected by ringer modes - if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || - (streamTypeAlias == getMasterStreamType())) { - int ringerMode = getRingerMode(); - // do not vibrate if already in vibrate mode - if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { - flags &= ~AudioManager.FLAG_VIBRATE; - } - // Check if the ringer mode changes with this volume adjustment. If - // it does, it will handle adjusting the volume, so we won't below - adjustVolume = checkForRingerModeChange(aliasIndex, direction, step); - if ((streamTypeAlias == getMasterStreamType()) && - (mRingerMode == AudioManager.RINGER_MODE_SILENT)) { - streamState.setLastAudibleIndex(0, device); - } - } - - // If stream is muted, adjust last audible index only - oldIndex = mStreamStates[streamType].getIndex(device, - (mStreamStates[streamType].muteCount() != 0) /* lastAudible */); - - if (streamState.muteCount() != 0) { - if (adjustVolume) { - // Post a persist volume msg - // no need to persist volume on all streams sharing the same alias - streamState.adjustLastAudibleIndex(direction * step, device); - sendMsg(mAudioHandler, - MSG_PERSIST_VOLUME, - SENDMSG_QUEUE, - PERSIST_LAST_AUDIBLE, - device, - streamState, - PERSIST_DELAY); - } - index = mStreamStates[streamType].getIndex(device, true /* lastAudible */); + flags &= ~AudioManager.FLAG_FIXED_VOLUME; + if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) && + ((device & mFixedVolumeDevices) != 0)) { + flags |= AudioManager.FLAG_FIXED_VOLUME; + index = mStreamStates[streamType].getMaxIndex(); + oldIndex = index; } else { - if (adjustVolume && streamState.adjustIndex(direction * step, device)) { - // Post message to set system volume (it in turn will post a message - // to persist). Do not change volume if stream is muted. - sendMsg(mAudioHandler, - MSG_SET_DEVICE_VOLUME, - SENDMSG_QUEUE, - device, - 0, - streamState, - 0); + // If either the client forces allowing ringer modes for this adjustment, + // or the stream type is one that is affected by ringer modes + if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || + (streamTypeAlias == getMasterStreamType())) { + int ringerMode = getRingerMode(); + // do not vibrate if already in vibrate mode + if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) { + flags &= ~AudioManager.FLAG_VIBRATE; + } + // Check if the ringer mode changes with this volume adjustment. If + // it does, it will handle adjusting the volume, so we won't below + adjustVolume = checkForRingerModeChange(aliasIndex, direction, step); + if ((streamTypeAlias == getMasterStreamType()) && + (mRingerMode == AudioManager.RINGER_MODE_SILENT)) { + streamState.setLastAudibleIndex(0, device); + } + } + + // If stream is muted, adjust last audible index only + oldIndex = mStreamStates[streamType].getIndex(device, + (mStreamStates[streamType].muteCount() != 0) /* lastAudible */); + + if (streamState.muteCount() != 0) { + if (adjustVolume) { + // Post a persist volume msg + // no need to persist volume on all streams sharing the same alias + streamState.adjustLastAudibleIndex(direction * step, device); + sendMsg(mAudioHandler, + MSG_PERSIST_VOLUME, + SENDMSG_QUEUE, + PERSIST_LAST_AUDIBLE, + device, + streamState, + PERSIST_DELAY); + } + index = mStreamStates[streamType].getIndex(device, true /* lastAudible */); + } else { + if (adjustVolume && streamState.adjustIndex(direction * step, device)) { + // Post message to set system volume (it in turn will post a message + // to persist). Do not change volume if stream is muted. + sendMsg(mAudioHandler, + MSG_SET_DEVICE_VOLUME, + SENDMSG_QUEUE, + device, + 0, + streamState, + 0); + } + index = mStreamStates[streamType].getIndex(device, false /* lastAudible */); } - index = mStreamStates[streamType].getIndex(device, false /* lastAudible */); } } sendVolumeUpdate(streamType, oldIndex, index, flags); @@ -2306,13 +2315,31 @@ public class AudioService extends IAudioService.Stub implements OnFinished { com.android.internal.R.integer.config_safe_media_volume_index) * 10; boolean safeMediaVolumeEnabled = mContext.getResources().getBoolean( com.android.internal.R.bool.config_safe_media_volume_enabled); + + // The persisted state is either "disabled" or "active": this is the state applied + // next time we boot and cannot be "inactive" + int persistedState; if (safeMediaVolumeEnabled) { - mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; - enforceSafeMediaVolume(); + persistedState = SAFE_MEDIA_VOLUME_ACTIVE; + // The state can already be "inactive" here if the user has forced it before + // the 30 seconds timeout for forced configuration. In this case we don't reset + // it to "active". + if (mSafeMediaVolumeState != SAFE_MEDIA_VOLUME_INACTIVE) { + mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_ACTIVE; + enforceSafeMediaVolume(); + } } else { + persistedState = SAFE_MEDIA_VOLUME_DISABLED; mSafeMediaVolumeState = SAFE_MEDIA_VOLUME_DISABLED; } mMcc = mcc; + sendMsg(mAudioHandler, + MSG_PERSIST_SAFE_VOLUME_STATE, + SENDMSG_QUEUE, + persistedState, + 0, + null, + 0); } } } @@ -3224,6 +3251,12 @@ public class AudioService extends IAudioService.Stub implements OnFinished { AudioSystem.setForceUse(usage, config); } + private void onPersistSafeVolumeState(int state) { + Settings.Global.putInt(mContentResolver, + Settings.Global.AUDIO_SAFE_VOLUME_STATE, + state); + } + @Override public void handleMessage(Message msg) { @@ -3433,6 +3466,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished { case MSG_CONFIGURE_SAFE_MEDIA_VOLUME: onConfigureSafeVolume((msg.what == MSG_CONFIGURE_SAFE_MEDIA_VOLUME_FORCED)); break; + case MSG_PERSIST_SAFE_VOLUME_STATE: + onPersistSafeVolumeState(msg.arg1); + break; } } } -- cgit v1.1 From 4df82703a7274876c03e65f7baf643f1ed55d29c Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 5 Dec 2012 11:12:26 -0800 Subject: Make it clear that non-optional MediaFormat keys are required Also mark KEY_CHANNEL_MASK optional. Change-Id: I569087f564dc60a89b15a3440a9b1c538927f610 related-to-bug: 7623602 --- media/java/android/media/MediaFormat.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'media/java') diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index 169502b..a2eb8d9 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -26,7 +26,7 @@ import java.util.Map; * * The format of the media data is specified as string/value pairs. * - * Keys common to all formats: + * Keys common to all formats, all keys not marked optional are mandatory: * * * @@ -52,7 +52,7 @@ import java.util.Map; * * * - * + * * *
NameValue TypeDescription
{@link #KEY_SAMPLE_RATE}Integer
{@link #KEY_IS_ADTS}Integeroptional, if decoding AAC audio content, setting this key to 1 indicates that each audio frame is prefixed by the ADTS header.
{@link #KEY_AAC_PROFILE}Integerencoder-only, optional, if content is AAC audio, specifies the desired profile.
{@link #KEY_CHANNEL_MASK}IntegerA mask of audio channel assignments
{@link #KEY_CHANNEL_MASK}Integeroptional, a mask of audio channel assignments
{@link #KEY_FLAC_COMPRESSION_LEVEL}Integerencoder-only, optional, if content is FLAC audio, specifies the desired compression level.
* -- cgit v1.1