mirror of
https://github.com/samsonjs/media.git
synced 2026-04-02 10:45:51 +00:00
parent
f60d2b4146
commit
5ab9a7856f
5 changed files with 53 additions and 67 deletions
|
|
@ -36,8 +36,6 @@
|
|||
([#1904](https://github.com/androidx/media/issues/1904)).
|
||||
* DataSource:
|
||||
* Audio:
|
||||
* Do not bypass `SonicAudioProcessor` when `SpeedChangingAudioProcessor`
|
||||
is configured with default parameters.
|
||||
* Video:
|
||||
* Rollback of using `MediaCodecAdapter` supplied pixel aspect ratio values
|
||||
when provided while processing `onOutputFormatChanged`
|
||||
|
|
|
|||
|
|
@ -15,11 +15,8 @@
|
|||
*/
|
||||
package androidx.media3.common.audio;
|
||||
|
||||
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static java.lang.Math.abs;
|
||||
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
|
|
@ -47,8 +44,6 @@ public class SonicAudioProcessor implements AudioProcessor {
|
|||
*/
|
||||
private static final int MIN_BYTES_FOR_DURATION_SCALING_CALCULATION = 1024;
|
||||
|
||||
private final boolean shouldBeActiveWithDefaultParameters;
|
||||
|
||||
private int pendingOutputSampleRate;
|
||||
private float speed;
|
||||
private float pitch;
|
||||
|
|
@ -69,17 +64,6 @@ public class SonicAudioProcessor implements AudioProcessor {
|
|||
|
||||
/** Creates a new Sonic audio processor. */
|
||||
public SonicAudioProcessor() {
|
||||
this(/* keepActiveWithDefaultParameters= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link SonicAudioProcessor}.
|
||||
*
|
||||
* <p>If {@code keepActiveWithDefaultParameters} is set to {@code true}, then {@link #isActive()}
|
||||
* returns {@code true} when parameters have been configured to default values that result in
|
||||
* no-op processing.
|
||||
*/
|
||||
/* package */ SonicAudioProcessor(boolean keepActiveWithDefaultParameters) {
|
||||
speed = 1f;
|
||||
pitch = 1f;
|
||||
pendingInputAudioFormat = AudioFormat.NOT_SET;
|
||||
|
|
@ -90,7 +74,6 @@ public class SonicAudioProcessor implements AudioProcessor {
|
|||
shortBuffer = buffer.asShortBuffer();
|
||||
outputBuffer = EMPTY_BUFFER;
|
||||
pendingOutputSampleRate = SAMPLE_RATE_NO_CHANGE;
|
||||
shouldBeActiveWithDefaultParameters = keepActiveWithDefaultParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -100,8 +83,7 @@ public class SonicAudioProcessor implements AudioProcessor {
|
|||
*
|
||||
* @param speed The target factor by which playback should be sped up.
|
||||
*/
|
||||
public final void setSpeed(@FloatRange(from = 0f, fromInclusive = false) float speed) {
|
||||
checkArgument(speed > 0f);
|
||||
public final void setSpeed(float speed) {
|
||||
if (this.speed != speed) {
|
||||
this.speed = speed;
|
||||
pendingSonicRecreation = true;
|
||||
|
|
@ -115,8 +97,7 @@ public class SonicAudioProcessor implements AudioProcessor {
|
|||
*
|
||||
* @param pitch The target pitch.
|
||||
*/
|
||||
public final void setPitch(@FloatRange(from = 0f, fromInclusive = false) float pitch) {
|
||||
checkArgument(pitch > 0f);
|
||||
public final void setPitch(float pitch) {
|
||||
if (this.pitch != pitch) {
|
||||
this.pitch = pitch;
|
||||
pendingSonicRecreation = true;
|
||||
|
|
@ -132,7 +113,6 @@ public class SonicAudioProcessor implements AudioProcessor {
|
|||
* @see #configure(AudioFormat)
|
||||
*/
|
||||
public final void setOutputSampleRateHz(int sampleRateHz) {
|
||||
checkArgument(sampleRateHz == SAMPLE_RATE_NO_CHANGE || sampleRateHz > 0);
|
||||
pendingOutputSampleRate = sampleRateHz;
|
||||
}
|
||||
|
||||
|
|
@ -216,13 +196,9 @@ public class SonicAudioProcessor implements AudioProcessor {
|
|||
@Override
|
||||
public final boolean isActive() {
|
||||
return pendingOutputAudioFormat.sampleRate != Format.NO_VALUE
|
||||
&& (shouldBeActiveWithDefaultParameters || !areParametersSetToDefaultValues());
|
||||
}
|
||||
|
||||
private boolean areParametersSetToDefaultValues() {
|
||||
return abs(speed - 1f) < CLOSE_THRESHOLD
|
||||
&& abs(pitch - 1f) < CLOSE_THRESHOLD
|
||||
&& pendingOutputAudioFormat.sampleRate == pendingInputAudioFormat.sampleRate;
|
||||
&& (Math.abs(speed - 1f) >= CLOSE_THRESHOLD
|
||||
|| Math.abs(pitch - 1f) >= CLOSE_THRESHOLD
|
||||
|| pendingOutputAudioFormat.sampleRate != pendingInputAudioFormat.sampleRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import static androidx.media3.common.util.Util.sampleCountToDurationUs;
|
|||
import static java.lang.Math.min;
|
||||
import static java.lang.Math.round;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.media3.common.C;
|
||||
|
|
@ -100,8 +99,7 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
|||
public SpeedChangingAudioProcessor(SpeedProvider speedProvider) {
|
||||
this.speedProvider = speedProvider;
|
||||
lock = new Object();
|
||||
sonicAudioProcessor =
|
||||
new SynchronizedSonicAudioProcessor(lock, /* keepActiveWithDefaultParameters= */ true);
|
||||
sonicAudioProcessor = new SynchronizedSonicAudioProcessor(lock);
|
||||
pendingCallbackInputTimesUs = new LongArrayQueue();
|
||||
pendingCallbacks = new ArrayDeque<>();
|
||||
speedAdjustedTimeAsyncInputTimeUs = C.TIME_UNSET;
|
||||
|
|
@ -176,11 +174,19 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
|||
}
|
||||
|
||||
long startPosition = inputBuffer.position();
|
||||
sonicAudioProcessor.queueInput(inputBuffer);
|
||||
if (bytesToNextSpeedChange != C.LENGTH_UNSET
|
||||
&& (inputBuffer.position() - startPosition) == bytesToNextSpeedChange) {
|
||||
sonicAudioProcessor.queueEndOfStream();
|
||||
endOfStreamQueuedToSonic = true;
|
||||
if (isUsingSonic()) {
|
||||
sonicAudioProcessor.queueInput(inputBuffer);
|
||||
if (bytesToNextSpeedChange != C.LENGTH_UNSET
|
||||
&& (inputBuffer.position() - startPosition) == bytesToNextSpeedChange) {
|
||||
sonicAudioProcessor.queueEndOfStream();
|
||||
endOfStreamQueuedToSonic = true;
|
||||
}
|
||||
} else {
|
||||
ByteBuffer buffer = replaceOutputBuffer(/* size= */ inputBuffer.remaining());
|
||||
if (inputBuffer.hasRemaining()) {
|
||||
buffer.put(inputBuffer);
|
||||
}
|
||||
buffer.flip();
|
||||
}
|
||||
long bytesRead = inputBuffer.position() - startPosition;
|
||||
checkState(
|
||||
|
|
@ -198,11 +204,9 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
// Not using BaseAudioProcessor's buffers.
|
||||
@SuppressLint("MissingSuperCall")
|
||||
@Override
|
||||
public ByteBuffer getOutput() {
|
||||
ByteBuffer output = sonicAudioProcessor.getOutput();
|
||||
ByteBuffer output = isUsingSonic() ? sonicAudioProcessor.getOutput() : super.getOutput();
|
||||
processPendingCallbacks();
|
||||
return output;
|
||||
}
|
||||
|
|
@ -347,8 +351,10 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
|||
if (newSpeed != currentSpeed) {
|
||||
updateSpeedChangeArrays(timeUs);
|
||||
currentSpeed = newSpeed;
|
||||
sonicAudioProcessor.setSpeed(newSpeed);
|
||||
sonicAudioProcessor.setPitch(newSpeed);
|
||||
if (isUsingSonic()) {
|
||||
sonicAudioProcessor.setSpeed(newSpeed);
|
||||
sonicAudioProcessor.setPitch(newSpeed);
|
||||
}
|
||||
// Invalidate any previously created buffers in SonicAudioProcessor and the base class.
|
||||
sonicAudioProcessor.flush();
|
||||
endOfStreamQueuedToSonic = false;
|
||||
|
|
@ -372,25 +378,39 @@ public final class SpeedChangingAudioProcessor extends BaseAudioProcessor {
|
|||
}
|
||||
|
||||
private long getPlayoutDurationUsAtCurrentSpeed(long mediaDurationUs) {
|
||||
return sonicAudioProcessor.getPlayoutDuration(mediaDurationUs);
|
||||
return isUsingSonic()
|
||||
? sonicAudioProcessor.getPlayoutDuration(mediaDurationUs)
|
||||
: mediaDurationUs;
|
||||
}
|
||||
|
||||
private long getMediaDurationUsAtCurrentSpeed(long playoutDurationUs) {
|
||||
return sonicAudioProcessor.getMediaDuration(playoutDurationUs);
|
||||
return isUsingSonic()
|
||||
? sonicAudioProcessor.getMediaDuration(playoutDurationUs)
|
||||
: playoutDurationUs;
|
||||
}
|
||||
|
||||
private void updateLastProcessedInputTime() {
|
||||
synchronized (lock) {
|
||||
// TODO - b/320242819: Investigate whether bytesRead can be used here rather than
|
||||
// sonicAudioProcessor.getProcessedInputBytes().
|
||||
long currentProcessedInputDurationUs =
|
||||
Util.scaleLargeTimestamp(
|
||||
/* timestamp= */ sonicAudioProcessor.getProcessedInputBytes(),
|
||||
/* multiplier= */ C.MICROS_PER_SECOND,
|
||||
/* divisor= */ (long) inputAudioFormat.sampleRate * inputAudioFormat.bytesPerFrame);
|
||||
lastProcessedInputTimeUs =
|
||||
inputSegmentStartTimesUs.get(inputSegmentStartTimesUs.size() - 1)
|
||||
+ currentProcessedInputDurationUs;
|
||||
if (isUsingSonic()) {
|
||||
// TODO - b/320242819: Investigate whether bytesRead can be used here rather than
|
||||
// sonicAudioProcessor.getProcessedInputBytes().
|
||||
long currentProcessedInputDurationUs =
|
||||
Util.scaleLargeTimestamp(
|
||||
/* timestamp= */ sonicAudioProcessor.getProcessedInputBytes(),
|
||||
/* multiplier= */ C.MICROS_PER_SECOND,
|
||||
/* divisor= */ (long) inputAudioFormat.sampleRate * inputAudioFormat.bytesPerFrame);
|
||||
lastProcessedInputTimeUs =
|
||||
inputSegmentStartTimesUs.get(inputSegmentStartTimesUs.size() - 1)
|
||||
+ currentProcessedInputDurationUs;
|
||||
} else {
|
||||
lastProcessedInputTimeUs = sampleCountToDurationUs(framesRead, inputAudioFormat.sampleRate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isUsingSonic() {
|
||||
synchronized (lock) {
|
||||
return currentSpeed != 1f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@ import java.nio.ByteBuffer;
|
|||
private final Object lock;
|
||||
private final SonicAudioProcessor sonicAudioProcessor;
|
||||
|
||||
public SynchronizedSonicAudioProcessor(Object lock, boolean keepActiveWithDefaultParameters) {
|
||||
public SynchronizedSonicAudioProcessor(Object lock) {
|
||||
this.lock = lock;
|
||||
sonicAudioProcessor = new SonicAudioProcessor(keepActiveWithDefaultParameters);
|
||||
sonicAudioProcessor = new SonicAudioProcessor();
|
||||
}
|
||||
|
||||
public final void setSpeed(float speed) {
|
||||
|
|
|
|||
|
|
@ -86,19 +86,11 @@ public final class SonicAudioProcessorTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void isActive_withDefaultParameters_returnsFalse() throws Exception {
|
||||
public void isNotActiveWithNoChange() throws Exception {
|
||||
sonicAudioProcessor.configure(AUDIO_FORMAT_44100_HZ);
|
||||
assertThat(sonicAudioProcessor.isActive()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isActive_keepActiveWithDefaultParameters_returnsTrue() throws Exception {
|
||||
SonicAudioProcessor processor =
|
||||
new SonicAudioProcessor(/* keepActiveWithDefaultParameters= */ true);
|
||||
processor.configure(AUDIO_FORMAT_44100_HZ);
|
||||
assertThat(processor.isActive()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesNotSupportNon16BitInput() throws Exception {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in a new issue