mirror of
https://github.com/androidx/media.git
synced 2025-05-07 23:50:44 +08:00
Select E-AC-3 in preference to AC-3, and remove other tracks.
This commit is contained in:
parent
3f1638de95
commit
e84c852169
@ -90,8 +90,17 @@ public class DashRendererBuilder implements RendererBuilder,
|
|||||||
private static final int SECURITY_LEVEL_1 = 1;
|
private static final int SECURITY_LEVEL_1 = 1;
|
||||||
private static final int SECURITY_LEVEL_3 = 3;
|
private static final int SECURITY_LEVEL_3 = 3;
|
||||||
|
|
||||||
private static final String AC_3_CODEC = "ac-3";
|
/**
|
||||||
private static final String E_AC_3_CODEC = "ec-3";
|
* Passthrough audio formats (encodings) in order of decreasing priority.
|
||||||
|
*/
|
||||||
|
private static final int[] PASSTHROUGH_ENCODINGS_PRIORITY =
|
||||||
|
new int[] {C.ENCODING_E_AC3, C.ENCODING_AC3};
|
||||||
|
/**
|
||||||
|
* Passthrough audio codecs corresponding to the encodings in
|
||||||
|
* {@link #PASSTHROUGH_ENCODINGS_PRIORITY}.
|
||||||
|
*/
|
||||||
|
private static final String[] PASSTHROUGH_CODECS_PRIORITY =
|
||||||
|
new String[] {"ec-3", "ac-3"};
|
||||||
|
|
||||||
private final String userAgent;
|
private final String userAgent;
|
||||||
private final String url;
|
private final String url;
|
||||||
@ -252,13 +261,14 @@ public class DashRendererBuilder implements RendererBuilder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build the audio chunk sources.
|
// Build the audio chunk sources.
|
||||||
boolean haveAc3Tracks = false;
|
|
||||||
List<ChunkSource> audioChunkSourceList = new ArrayList<ChunkSource>();
|
List<ChunkSource> audioChunkSourceList = new ArrayList<ChunkSource>();
|
||||||
List<String> audioTrackNameList = new ArrayList<String>();
|
List<String> audioTrackNameList = new ArrayList<String>();
|
||||||
|
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
|
||||||
if (audioAdaptationSet != null) {
|
if (audioAdaptationSet != null) {
|
||||||
DataSource audioDataSource = new UriDataSource(userAgent, bandwidthMeter);
|
DataSource audioDataSource = new UriDataSource(userAgent, bandwidthMeter);
|
||||||
FormatEvaluator audioEvaluator = new FormatEvaluator.FixedEvaluator();
|
FormatEvaluator audioEvaluator = new FormatEvaluator.FixedEvaluator();
|
||||||
List<Representation> audioRepresentations = audioAdaptationSet.representations;
|
List<Representation> audioRepresentations = audioAdaptationSet.representations;
|
||||||
|
List<String> codecs = new ArrayList<String>();
|
||||||
for (int i = 0; i < audioRepresentations.size(); i++) {
|
for (int i = 0; i < audioRepresentations.size(); i++) {
|
||||||
Format format = audioRepresentations.get(i).format;
|
Format format = audioRepresentations.get(i).format;
|
||||||
audioTrackNameList.add(format.id + " (" + format.numChannels + "ch, " +
|
audioTrackNameList.add(format.id + " (" + format.numChannels + "ch, " +
|
||||||
@ -266,16 +276,27 @@ public class DashRendererBuilder implements RendererBuilder,
|
|||||||
audioChunkSourceList.add(new DashChunkSource(manifestFetcher, audioAdaptationSetIndex,
|
audioChunkSourceList.add(new DashChunkSource(manifestFetcher, audioAdaptationSetIndex,
|
||||||
new int[] {i}, audioDataSource, audioEvaluator, LIVE_EDGE_LATENCY_MS,
|
new int[] {i}, audioDataSource, audioEvaluator, LIVE_EDGE_LATENCY_MS,
|
||||||
elapsedRealtimeOffset));
|
elapsedRealtimeOffset));
|
||||||
haveAc3Tracks |= AC_3_CODEC.equals(format.codecs) || E_AC_3_CODEC.equals(format.codecs);
|
codecs.add(format.codecs);
|
||||||
}
|
}
|
||||||
// Filter out non-AC-3 tracks if there is an AC-3 track, to avoid having to switch renderers.
|
|
||||||
if (haveAc3Tracks) {
|
if (audioCapabilities != null) {
|
||||||
for (int i = audioRepresentations.size() - 1; i >= 0; i--) {
|
// If there are any passthrough audio encodings available, select the highest priority
|
||||||
Format format = audioRepresentations.get(i).format;
|
// supported format (e.g. E-AC-3) and remove other tracks.
|
||||||
if (!AC_3_CODEC.equals(format.codecs) && !E_AC_3_CODEC.equals(format.codecs)) {
|
for (int i = 0; i < PASSTHROUGH_CODECS_PRIORITY.length; i++) {
|
||||||
audioTrackNameList.remove(i);
|
String codec = PASSTHROUGH_CODECS_PRIORITY[i];
|
||||||
audioChunkSourceList.remove(i);
|
int encoding = PASSTHROUGH_ENCODINGS_PRIORITY[i];
|
||||||
|
if (codecs.indexOf(codec) == -1 || !audioCapabilities.supportsEncoding(encoding)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
audioEncoding = encoding;
|
||||||
|
for (int j = audioRepresentations.size() - 1; j >= 0; j--) {
|
||||||
|
if (!audioRepresentations.get(j).format.codecs.equals(codec)) {
|
||||||
|
audioTrackNameList.remove(j);
|
||||||
|
audioChunkSourceList.remove(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,11 +316,8 @@ public class DashRendererBuilder implements RendererBuilder,
|
|||||||
SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
|
SampleSource audioSampleSource = new ChunkSampleSource(audioChunkSource, loadControl,
|
||||||
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player,
|
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, mainHandler, player,
|
||||||
DemoPlayer.TYPE_AUDIO);
|
DemoPlayer.TYPE_AUDIO);
|
||||||
// TODO: There needs to be some logic to filter out non-AC3 tracks when selecting to use AC3.
|
|
||||||
boolean useAc3Passthrough = haveAc3Tracks && audioCapabilities != null
|
|
||||||
&& (audioCapabilities.supportsAc3() || audioCapabilities.supportsEAc3());
|
|
||||||
audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true,
|
audioRenderer = new MediaCodecAudioTrackRenderer(audioSampleSource, drmSessionManager, true,
|
||||||
mainHandler, player, useAc3Passthrough ? C.ENCODING_AC3 : AudioFormat.ENCODING_PCM_16BIT);
|
mainHandler, player, audioEncoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the text chunk sources.
|
// Build the text chunk sources.
|
||||||
|
@ -56,6 +56,12 @@ public final class C {
|
|||||||
@SuppressWarnings("InlinedApi")
|
@SuppressWarnings("InlinedApi")
|
||||||
public static final int ENCODING_AC3 = AudioFormat.ENCODING_AC3;
|
public static final int ENCODING_AC3 = AudioFormat.ENCODING_AC3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AudioFormat#ENCODING_E_AC3
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("InlinedApi")
|
||||||
|
public static final int ENCODING_E_AC3 = AudioFormat.ENCODING_E_AC3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see MediaExtractor#SAMPLE_FLAG_SYNC
|
* @see MediaExtractor#SAMPLE_FLAG_SYNC
|
||||||
*/
|
*/
|
||||||
|
@ -15,13 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.audio;
|
package com.google.android.exoplayer.audio;
|
||||||
|
|
||||||
import com.google.android.exoplayer.util.Util;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.media.AudioFormat;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the set of audio formats a device is capable of playing back.
|
* Represents the set of audio formats a device is capable of playing back.
|
||||||
@ -29,7 +25,7 @@ import java.util.Set;
|
|||||||
@TargetApi(21)
|
@TargetApi(21)
|
||||||
public final class AudioCapabilities {
|
public final class AudioCapabilities {
|
||||||
|
|
||||||
private final Set<Integer> supportedEncodings;
|
private final int[] supportedEncodings;
|
||||||
private final int maxChannelCount;
|
private final int maxChannelCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,28 +37,20 @@ public final class AudioCapabilities {
|
|||||||
* @param maxChannelCount The maximum number of audio channels that can be played simultaneously.
|
* @param maxChannelCount The maximum number of audio channels that can be played simultaneously.
|
||||||
*/
|
*/
|
||||||
public AudioCapabilities(int[] supportedEncodings, int maxChannelCount) {
|
public AudioCapabilities(int[] supportedEncodings, int maxChannelCount) {
|
||||||
this.supportedEncodings = new HashSet<Integer>();
|
this.supportedEncodings = supportedEncodings != null ? supportedEncodings : new int[0];
|
||||||
if (supportedEncodings != null) {
|
|
||||||
for (int i : supportedEncodings) {
|
|
||||||
this.supportedEncodings.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.maxChannelCount = maxChannelCount;
|
this.maxChannelCount = maxChannelCount;
|
||||||
|
|
||||||
|
Arrays.sort(supportedEncodings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether the device supports playback of AC-3. */
|
/**
|
||||||
public boolean supportsAc3() {
|
* Returns whether this device supports playback of the specified audio {@code encoding}.
|
||||||
return Util.SDK_INT >= 21 && supportedEncodings.contains(AudioFormat.ENCODING_AC3);
|
*
|
||||||
}
|
* @param encoding One of {@link android.media.AudioFormat}'s {@code ENCODING_*} constants.
|
||||||
|
* @return Whether this device supports playback the specified audio {@code encoding}.
|
||||||
/** Returns whether the device supports playback of enhanced AC-3. */
|
*/
|
||||||
public boolean supportsEAc3() {
|
public boolean supportsEncoding(int encoding) {
|
||||||
return Util.SDK_INT >= 21 && supportedEncodings.contains(AudioFormat.ENCODING_E_AC3);
|
return Arrays.binarySearch(supportedEncodings, encoding) >= 0;
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether the device supports playback of 16-bit PCM. */
|
|
||||||
public boolean supportsPcm() {
|
|
||||||
return supportedEncodings.contains(AudioFormat.ENCODING_PCM_16BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the maximum number of channels the device can play at the same time. */
|
/** Returns the maximum number of channels the device can play at the same time. */
|
||||||
@ -79,19 +67,19 @@ public final class AudioCapabilities {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AudioCapabilities audioCapabilities = (AudioCapabilities) other;
|
AudioCapabilities audioCapabilities = (AudioCapabilities) other;
|
||||||
return supportedEncodings.equals(audioCapabilities.supportedEncodings)
|
return Arrays.equals(supportedEncodings, audioCapabilities.supportedEncodings)
|
||||||
&& maxChannelCount == audioCapabilities.maxChannelCount;
|
&& maxChannelCount == audioCapabilities.maxChannelCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return maxChannelCount + 31 * supportedEncodings.hashCode();
|
return maxChannelCount + 31 * Arrays.hashCode(supportedEncodings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "AudioCapabilities[maxChannelCount=" + maxChannelCount
|
return "AudioCapabilities[maxChannelCount=" + maxChannelCount
|
||||||
+ ", supportedEncodings=" + supportedEncodings + "]";
|
+ ", supportedEncodings=" + Arrays.toString(supportedEncodings) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user