Create Timestamp iterator
PiperOrigin-RevId: 558738035
This commit is contained in:
parent
352916b182
commit
521c210fd1
@ -23,12 +23,12 @@ import android.opengl.EGLExt;
|
|||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.media3.common.util.TimestampIterator;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ public interface VideoFrameProcessor {
|
|||||||
* @throws UnsupportedOperationException If the {@code VideoFrameProcessor} does not accept
|
* @throws UnsupportedOperationException If the {@code VideoFrameProcessor} does not accept
|
||||||
* {@linkplain #INPUT_TYPE_BITMAP bitmap input}.
|
* {@linkplain #INPUT_TYPE_BITMAP bitmap input}.
|
||||||
*/
|
*/
|
||||||
void queueInputBitmap(Bitmap inputBitmap, Iterator<Long> inStreamOffsetsUs);
|
void queueInputBitmap(Bitmap inputBitmap, TimestampIterator inStreamOffsetsUs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides an input texture ID to the {@code VideoFrameProcessor}.
|
* Provides an input texture ID to the {@code VideoFrameProcessor}.
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package androidx.media3.common.util;
|
||||||
|
|
||||||
|
import static androidx.media3.common.util.Assertions.checkArgument;
|
||||||
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
|
import static java.lang.Math.round;
|
||||||
|
|
||||||
|
import androidx.annotation.FloatRange;
|
||||||
|
import androidx.annotation.IntRange;
|
||||||
|
import androidx.media3.common.C;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link TimestampIterator} that generates monotonically increasing timestamps (in microseconds)
|
||||||
|
* distributed evenly over the given {@code durationUs} based on the given {@code frameRate}.
|
||||||
|
*/
|
||||||
|
@UnstableApi
|
||||||
|
public final class ConstantRateTimestampIterator implements TimestampIterator {
|
||||||
|
|
||||||
|
private final double framesDurationUs;
|
||||||
|
private double currentTimestampUs;
|
||||||
|
private int framesToAdd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance.
|
||||||
|
*
|
||||||
|
* @param durationUs The duration the timestamps should span over, in microseconds.
|
||||||
|
* @param frameRate The frame rate in frames per second.
|
||||||
|
*/
|
||||||
|
public ConstantRateTimestampIterator(
|
||||||
|
@IntRange(from = 1) long durationUs,
|
||||||
|
@FloatRange(from = 0, fromInclusive = false) float frameRate) {
|
||||||
|
checkArgument(durationUs > 0);
|
||||||
|
checkArgument(frameRate > 0);
|
||||||
|
framesToAdd = round(frameRate * (durationUs / (float) C.MICROS_PER_SECOND));
|
||||||
|
framesDurationUs = C.MICROS_PER_SECOND / frameRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return framesToAdd != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long next() {
|
||||||
|
checkState(hasNext());
|
||||||
|
framesToAdd--;
|
||||||
|
long next = round(currentTimestampUs);
|
||||||
|
currentTimestampUs += framesDurationUs;
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package androidx.media3.common.util;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
/** A primitive long iterator used for generating sequences of timestamps. */
|
||||||
|
@UnstableApi
|
||||||
|
public interface TimestampIterator {
|
||||||
|
|
||||||
|
/** Returns whether there is another element. */
|
||||||
|
boolean hasNext();
|
||||||
|
|
||||||
|
/** Returns the next timestamp. */
|
||||||
|
long next();
|
||||||
|
|
||||||
|
/** Creates TimestampIterator */
|
||||||
|
static TimestampIterator createFromLongIterator(Iterator<Long> iterator) {
|
||||||
|
return new TimestampIterator() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return iterator.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long next() {
|
||||||
|
return iterator.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package androidx.media3.common.util;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import androidx.media3.common.C;
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
/** Unit tests for {@link ConstantRateTimestampIterator}. */
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ConstantRateTimestampIteratorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void timestampIterator_validArguments_generatesCorrectTimestamps() throws Exception {
|
||||||
|
ConstantRateTimestampIterator constantRateTimestampIterator =
|
||||||
|
new ConstantRateTimestampIterator(C.MICROS_PER_SECOND, /* frameRate= */ 2);
|
||||||
|
|
||||||
|
assertThat(generateList(constantRateTimestampIterator))
|
||||||
|
.containsExactly(0L, C.MICROS_PER_SECOND / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void timestampIterator_realisticArguments_generatesCorrectNumberOfTimestamps()
|
||||||
|
throws Exception {
|
||||||
|
ConstantRateTimestampIterator constantRateTimestampIterator =
|
||||||
|
new ConstantRateTimestampIterator((long) (2.5 * C.MICROS_PER_SECOND), /* frameRate= */ 30);
|
||||||
|
|
||||||
|
assertThat(generateList(constantRateTimestampIterator)).hasSize(75);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void timestampIterator_realisticArguments_generatesTimestampsInStrictOrder()
|
||||||
|
throws Exception {
|
||||||
|
ConstantRateTimestampIterator constantRateTimestampIterator =
|
||||||
|
new ConstantRateTimestampIterator((long) (2.5 * C.MICROS_PER_SECOND), /* frameRate= */ 30);
|
||||||
|
|
||||||
|
assertThat(generateList(constantRateTimestampIterator)).isInStrictOrder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void timestampIterator_realisticArguments_doesNotGenerateDuplicates() throws Exception {
|
||||||
|
ConstantRateTimestampIterator constantRateTimestampIterator =
|
||||||
|
new ConstantRateTimestampIterator((long) (2.5 * C.MICROS_PER_SECOND), /* frameRate= */ 30);
|
||||||
|
|
||||||
|
assertThat(generateList(constantRateTimestampIterator)).containsNoDuplicates();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void timestampIterator_smallDuration_generatesEmptyIterator() throws Exception {
|
||||||
|
ConstantRateTimestampIterator constantRateTimestampIterator =
|
||||||
|
new ConstantRateTimestampIterator(/* durationUs= */ 1, /* frameRate= */ 2);
|
||||||
|
|
||||||
|
assertThat(generateList(constantRateTimestampIterator)).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Long> generateList(TimestampIterator iterator) {
|
||||||
|
ArrayList<Long> list = new ArrayList<>();
|
||||||
|
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
list.add(iterator.next());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@
|
|||||||
package androidx.media3.effect;
|
package androidx.media3.effect;
|
||||||
|
|
||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
|
import static androidx.media3.common.util.TimestampIterator.createFromLongIterator;
|
||||||
import static androidx.media3.test.utils.BitmapPixelTestUtil.readBitmap;
|
import static androidx.media3.test.utils.BitmapPixelTestUtil.readBitmap;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@ -209,8 +210,9 @@ public class DefaultVideoFrameProcessorImageFrameOutputTest {
|
|||||||
videoFrameProcessorTestRunner.queueInputBitmaps(
|
videoFrameProcessorTestRunner.queueInputBitmaps(
|
||||||
bitmap1.getWidth(),
|
bitmap1.getWidth(),
|
||||||
bitmap1.getHeight(),
|
bitmap1.getHeight(),
|
||||||
Pair.create(bitmap1, ImmutableList.of(offset1).iterator()),
|
Pair.create(bitmap1, createFromLongIterator(ImmutableList.of(offset1).iterator())),
|
||||||
Pair.create(bitmap2, ImmutableList.of(offset2, offset3).iterator()));
|
Pair.create(
|
||||||
|
bitmap2, createFromLongIterator(ImmutableList.of(offset2, offset3).iterator())));
|
||||||
videoFrameProcessorTestRunner.endFrameProcessing();
|
videoFrameProcessorTestRunner.endFrameProcessing();
|
||||||
|
|
||||||
assertThat(actualPresentationTimesUs).containsExactly(offset1, offset2, offset3).inOrder();
|
assertThat(actualPresentationTimesUs).containsExactly(offset1, offset2, offset3).inOrder();
|
||||||
|
@ -52,13 +52,13 @@ import androidx.media3.common.VideoFrameProcessingException;
|
|||||||
import androidx.media3.common.VideoFrameProcessor;
|
import androidx.media3.common.VideoFrameProcessor;
|
||||||
import androidx.media3.common.util.GlUtil;
|
import androidx.media3.common.util.GlUtil;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
|
import androidx.media3.common.util.TimestampIterator;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
import androidx.media3.common.util.Util;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -438,7 +438,7 @@ public final class DefaultVideoFrameProcessor implements VideoFrameProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void queueInputBitmap(Bitmap inputBitmap, Iterator<Long> inStreamOffsetsUs) {
|
public void queueInputBitmap(Bitmap inputBitmap, TimestampIterator inStreamOffsetsUs) {
|
||||||
FrameInfo frameInfo = checkNotNull(this.nextInputFrameInfo);
|
FrameInfo frameInfo = checkNotNull(this.nextInputFrameInfo);
|
||||||
// TODO(b/262693274): move frame duplication logic out of the texture manager so
|
// TODO(b/262693274): move frame duplication logic out of the texture manager so
|
||||||
// textureManager.queueInputBitmap() frame rate and duration parameters be removed.
|
// textureManager.queueInputBitmap() frame rate and duration parameters be removed.
|
||||||
|
@ -45,11 +45,11 @@ import androidx.media3.common.SurfaceInfo;
|
|||||||
import androidx.media3.common.VideoFrameProcessingException;
|
import androidx.media3.common.VideoFrameProcessingException;
|
||||||
import androidx.media3.common.VideoFrameProcessor;
|
import androidx.media3.common.VideoFrameProcessor;
|
||||||
import androidx.media3.common.util.GlUtil;
|
import androidx.media3.common.util.GlUtil;
|
||||||
|
import androidx.media3.common.util.TimestampIterator;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
@ -359,14 +359,14 @@ public final class VideoFrameProcessorTestRunner {
|
|||||||
videoFrameProcessor.queueInputBitmap(inputBitmap, durationUs, frameRate);
|
videoFrameProcessor.queueInputBitmap(inputBitmap, durationUs, frameRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void queueInputBitmaps(int width, int height, Pair<Bitmap, Iterator<Long>>... frames) {
|
public void queueInputBitmaps(int width, int height, Pair<Bitmap, TimestampIterator>... frames) {
|
||||||
videoFrameProcessor.registerInputStream(
|
videoFrameProcessor.registerInputStream(
|
||||||
INPUT_TYPE_BITMAP,
|
INPUT_TYPE_BITMAP,
|
||||||
effects,
|
effects,
|
||||||
new FrameInfo.Builder(width, height)
|
new FrameInfo.Builder(width, height)
|
||||||
.setPixelWidthHeightRatio(pixelWidthHeightRatio)
|
.setPixelWidthHeightRatio(pixelWidthHeightRatio)
|
||||||
.build());
|
.build());
|
||||||
for (Pair<Bitmap, Iterator<Long>> frame : frames) {
|
for (Pair<Bitmap, TimestampIterator> frame : frames) {
|
||||||
videoFrameProcessor.queueInputBitmap(frame.first, frame.second);
|
videoFrameProcessor.queueInputBitmap(frame.first, frame.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ import android.view.Surface;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.ColorInfo;
|
import androidx.media3.common.ColorInfo;
|
||||||
import androidx.media3.common.OnInputFrameProcessedListener;
|
import androidx.media3.common.OnInputFrameProcessedListener;
|
||||||
|
import androidx.media3.common.util.TimestampIterator;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.decoder.DecoderInputBuffer;
|
import androidx.media3.decoder.DecoderInputBuffer;
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/** Consumer of encoded media samples, raw audio or raw video frames. */
|
/** Consumer of encoded media samples, raw audio or raw video frames. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
@ -93,7 +93,7 @@ public interface SampleConsumer {
|
|||||||
* @param inStreamOffsetsUs The times within the current stream that the bitmap should be
|
* @param inStreamOffsetsUs The times within the current stream that the bitmap should be
|
||||||
* displayed at. The timestamps should be monotonically increasing.
|
* displayed at. The timestamps should be monotonically increasing.
|
||||||
*/
|
*/
|
||||||
default boolean queueInputBitmap(Bitmap inputBitmap, Iterator<Long> inStreamOffsetsUs) {
|
default boolean queueInputBitmap(Bitmap inputBitmap, TimestampIterator inStreamOffsetsUs) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +35,11 @@ import androidx.media3.common.MimeTypes;
|
|||||||
import androidx.media3.common.OnInputFrameProcessedListener;
|
import androidx.media3.common.OnInputFrameProcessedListener;
|
||||||
import androidx.media3.common.util.Clock;
|
import androidx.media3.common.util.Clock;
|
||||||
import androidx.media3.common.util.HandlerWrapper;
|
import androidx.media3.common.util.HandlerWrapper;
|
||||||
|
import androidx.media3.common.util.TimestampIterator;
|
||||||
import androidx.media3.decoder.DecoderInputBuffer;
|
import androidx.media3.decoder.DecoderInputBuffer;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
@ -349,17 +349,16 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an {@link Iterator}, creates an iterator that includes all the values in the original
|
* Wraps a {@link TimestampIterator}, providing all the values in the original timestamp iterator
|
||||||
* iterator (in the same order) up to and including the first occurrence of the {@code
|
* (in the same order) up to and including the first occurrence of the {@code clippingValue}.
|
||||||
* clippingValue}.
|
|
||||||
*/
|
*/
|
||||||
private static final class ClippingIterator implements Iterator<Long> {
|
private static final class ClippingIterator implements TimestampIterator {
|
||||||
|
|
||||||
private final Iterator<Long> iterator;
|
private final TimestampIterator iterator;
|
||||||
private final long clippingValue;
|
private final long clippingValue;
|
||||||
private boolean hasReachedClippingValue;
|
private boolean hasReachedClippingValue;
|
||||||
|
|
||||||
public ClippingIterator(Iterator<Long> iterator, long clippingValue) {
|
public ClippingIterator(TimestampIterator iterator, long clippingValue) {
|
||||||
this.iterator = iterator;
|
this.iterator = iterator;
|
||||||
this.clippingValue = clippingValue;
|
this.clippingValue = clippingValue;
|
||||||
}
|
}
|
||||||
@ -370,9 +369,9 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long next() {
|
public long next() {
|
||||||
checkState(hasNext());
|
checkState(hasNext());
|
||||||
Long next = iterator.next();
|
long next = iterator.next();
|
||||||
if (clippingValue == next) {
|
if (clippingValue == next) {
|
||||||
hasReachedClippingValue = true;
|
hasReachedClippingValue = true;
|
||||||
}
|
}
|
||||||
@ -450,8 +449,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean queueInputBitmap(Bitmap inputBitmap, Iterator<Long> inStreamOffsetsUs) {
|
public boolean queueInputBitmap(Bitmap inputBitmap, TimestampIterator inStreamOffsetsUs) {
|
||||||
Iterator<Long> iteratorToUse = inStreamOffsetsUs;
|
TimestampIterator iteratorToUse = inStreamOffsetsUs;
|
||||||
if (isLooping) {
|
if (isLooping) {
|
||||||
long durationLeftUs = maxSequenceDurationUs - totalDurationUs;
|
long durationLeftUs = maxSequenceDurationUs - totalDurationUs;
|
||||||
if (durationLeftUs <= 0) {
|
if (durationLeftUs <= 0) {
|
||||||
|
@ -37,9 +37,9 @@ import androidx.media3.common.VideoFrameProcessingException;
|
|||||||
import androidx.media3.common.VideoFrameProcessor;
|
import androidx.media3.common.VideoFrameProcessor;
|
||||||
import androidx.media3.common.util.Consumer;
|
import androidx.media3.common.util.Consumer;
|
||||||
import androidx.media3.common.util.Size;
|
import androidx.media3.common.util.Size;
|
||||||
|
import androidx.media3.common.util.TimestampIterator;
|
||||||
import androidx.media3.effect.Presentation;
|
import androidx.media3.effect.Presentation;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@ -175,7 +175,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean queueInputBitmap(Bitmap inputBitmap, Iterator<Long> inStreamOffsetsUs) {
|
public boolean queueInputBitmap(Bitmap inputBitmap, TimestampIterator inStreamOffsetsUs) {
|
||||||
videoFrameProcessor.queueInputBitmap(inputBitmap, inStreamOffsetsUs);
|
videoFrameProcessor.queueInputBitmap(inputBitmap, inStreamOffsetsUs);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user