mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Enable non-reference frame skipping in FrameExtractor
Speed up FrameExtractor for videos with non-ref frames PiperOrigin-RevId: 715789816
This commit is contained in:
parent
c5feb28838
commit
0936b549ae
@ -21,7 +21,9 @@ import static androidx.media3.exoplayer.SeekParameters.CLOSEST_SYNC;
|
|||||||
import static androidx.media3.test.utils.BitmapPixelTestUtil.maybeSaveTestBitmap;
|
import static androidx.media3.test.utils.BitmapPixelTestUtil.maybeSaveTestBitmap;
|
||||||
import static androidx.media3.test.utils.BitmapPixelTestUtil.readBitmap;
|
import static androidx.media3.test.utils.BitmapPixelTestUtil.readBitmap;
|
||||||
import static androidx.media3.test.utils.TestUtil.assertBitmapsAreSimilar;
|
import static androidx.media3.test.utils.TestUtil.assertBitmapsAreSimilar;
|
||||||
|
import static androidx.media3.transformer.AndroidTestUtil.MP4_ASSET;
|
||||||
import static androidx.media3.transformer.AndroidTestUtil.MP4_TRIM_OPTIMIZATION_270;
|
import static androidx.media3.transformer.AndroidTestUtil.MP4_TRIM_OPTIMIZATION_270;
|
||||||
|
import static androidx.media3.transformer.AndroidTestUtil.assumeFormatsSupported;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
|
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
@ -473,4 +475,26 @@ public class FrameExtractorTest {
|
|||||||
assertThat(frameSecondItem.presentationTimeMs).isEqualTo(8_531);
|
assertThat(frameSecondItem.presentationTimeMs).isEqualTo(8_531);
|
||||||
assertBitmapsAreSimilar(expectedBitmapSecondItem, actualBitmapSecondItem, PSNR_THRESHOLD);
|
assertBitmapsAreSimilar(expectedBitmapSecondItem, actualBitmapSecondItem, PSNR_THRESHOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractFrame_oneFrame_decodesReferenceFramesOnly() throws Exception {
|
||||||
|
assumeFormatsSupported(
|
||||||
|
context, testId, /* inputFormat= */ MP4_ASSET.videoFormat, /* outputFormat= */ null);
|
||||||
|
frameExtractor =
|
||||||
|
new ExperimentalFrameExtractor(
|
||||||
|
context, new ExperimentalFrameExtractor.Configuration.Builder().build());
|
||||||
|
frameExtractor.setMediaItem(
|
||||||
|
MediaItem.fromUri(MP4_ASSET.uri), /* effects= */ ImmutableList.of());
|
||||||
|
|
||||||
|
ListenableFuture<Frame> frameFuture = frameExtractor.getFrame(/* positionMs= */ 967);
|
||||||
|
Frame frame = frameFuture.get(TIMEOUT_SECONDS, SECONDS);
|
||||||
|
|
||||||
|
assertThat(frame.presentationTimeMs).isEqualTo(967);
|
||||||
|
assertThat(
|
||||||
|
frameExtractor
|
||||||
|
.getDecoderCounters()
|
||||||
|
.get(TIMEOUT_SECONDS, SECONDS)
|
||||||
|
.skippedInputBufferCount)
|
||||||
|
.isEqualTo(13);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import androidx.concurrent.futures.CallbackToFutureAdapter;
|
import androidx.concurrent.futures.CallbackToFutureAdapter;
|
||||||
|
import androidx.media3.common.C;
|
||||||
import androidx.media3.common.Effect;
|
import androidx.media3.common.Effect;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.GlObjectsProvider;
|
import androidx.media3.common.GlObjectsProvider;
|
||||||
@ -80,9 +81,11 @@ import androidx.media3.exoplayer.analytics.AnalyticsListener;
|
|||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecAdapter;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecAdapter;
|
||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecInfo;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecInfo;
|
||||||
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector;
|
||||||
|
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
|
||||||
import androidx.media3.exoplayer.source.MediaSource;
|
import androidx.media3.exoplayer.source.MediaSource;
|
||||||
import androidx.media3.exoplayer.video.MediaCodecVideoRenderer;
|
import androidx.media3.exoplayer.video.MediaCodecVideoRenderer;
|
||||||
import androidx.media3.exoplayer.video.VideoRendererEventListener;
|
import androidx.media3.exoplayer.video.VideoRendererEventListener;
|
||||||
|
import androidx.media3.extractor.DefaultExtractorsFactory;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
@ -273,6 +276,10 @@ public final class ExperimentalFrameExtractor {
|
|||||||
* @param configuration The {@link Configuration} for this frame extractor.
|
* @param configuration The {@link Configuration} for this frame extractor.
|
||||||
*/
|
*/
|
||||||
public ExperimentalFrameExtractor(Context context, Configuration configuration) {
|
public ExperimentalFrameExtractor(Context context, Configuration configuration) {
|
||||||
|
MediaSource.Factory mediaSourceFactory =
|
||||||
|
new DefaultMediaSourceFactory(context, new DefaultExtractorsFactory())
|
||||||
|
.experimentalSetCodecsToParseWithinGopSampleDependencies(
|
||||||
|
C.VIDEO_CODEC_FLAG_H264 | C.VIDEO_CODEC_FLAG_H265);
|
||||||
player =
|
player =
|
||||||
new ExoPlayer.Builder(
|
new ExoPlayer.Builder(
|
||||||
context,
|
context,
|
||||||
@ -287,7 +294,8 @@ public final class ExperimentalFrameExtractor {
|
|||||||
configuration.mediaCodecSelector,
|
configuration.mediaCodecSelector,
|
||||||
videoRendererEventListener,
|
videoRendererEventListener,
|
||||||
/* toneMapHdrToSdr= */ !configuration.extractHdrFrames)
|
/* toneMapHdrToSdr= */ !configuration.extractHdrFrames)
|
||||||
})
|
},
|
||||||
|
mediaSourceFactory)
|
||||||
.setSeekParameters(configuration.seekParameters)
|
.setSeekParameters(configuration.seekParameters)
|
||||||
.build();
|
.build();
|
||||||
player.addAnalyticsListener(new PlayerListener());
|
player.addAnalyticsListener(new PlayerListener());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user