Support Jpeg image track extraction in exoplayer

PiperOrigin-RevId: 563818198
This commit is contained in:
tofunmi 2023-09-08 12:12:15 -07:00 committed by Copybara-Service
parent be5fa6d130
commit 23665090ed
4 changed files with 34 additions and 3 deletions

View File

@ -48,6 +48,7 @@ import androidx.media3.extractor.ExtractorsFactory;
import androidx.media3.extractor.PositionHolder; import androidx.media3.extractor.PositionHolder;
import androidx.media3.extractor.SeekMap; import androidx.media3.extractor.SeekMap;
import androidx.media3.extractor.TrackOutput; import androidx.media3.extractor.TrackOutput;
import androidx.media3.extractor.jpeg.JpegExtractor;
import androidx.media3.extractor.text.DefaultSubtitleParserFactory; import androidx.media3.extractor.text.DefaultSubtitleParserFactory;
import androidx.media3.extractor.text.SubtitleExtractor; import androidx.media3.extractor.text.SubtitleExtractor;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -438,6 +439,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
int type = int type =
Util.inferContentTypeForUriAndMimeType( Util.inferContentTypeForUriAndMimeType(
mediaItem.localConfiguration.uri, mediaItem.localConfiguration.mimeType); mediaItem.localConfiguration.uri, mediaItem.localConfiguration.mimeType);
if (mediaItem.localConfiguration.imageDurationMs != C.TIME_UNSET) {
delegateFactoryLoader.setJpegExtractorFlags(JpegExtractor.FLAG_READ_IMAGE);
}
@Nullable @Nullable
MediaSource.Factory mediaSourceFactory = delegateFactoryLoader.getMediaSourceFactory(type); MediaSource.Factory mediaSourceFactory = delegateFactoryLoader.getMediaSourceFactory(type);
checkStateNotNull( checkStateNotNull(
@ -650,6 +654,12 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
} }
} }
public void setJpegExtractorFlags(@JpegExtractor.Flags int flags) {
if (this.extractorsFactory instanceof DefaultExtractorsFactory) {
((DefaultExtractorsFactory) this.extractorsFactory).setJpegExtractorFlags(flags);
}
}
private void ensureAllSuppliersAreLoaded() { private void ensureAllSuppliersAreLoaded() {
maybeLoadSupplier(C.CONTENT_TYPE_DASH); maybeLoadSupplier(C.CONTENT_TYPE_DASH);
maybeLoadSupplier(C.CONTENT_TYPE_SS); maybeLoadSupplier(C.CONTENT_TYPE_SS);

View File

@ -50,8 +50,9 @@ public class ImagePlaybackTest {
// TODO(b/289989736): When extraction for other types of images is implemented, add those image // TODO(b/289989736): When extraction for other types of images is implemented, add those image
// types to this list. // types to this list.
// Robolectric's NativeShadowBitmapFactory doesn't support decoding HEIF format, so we don't // Robolectric's NativeShadowBitmapFactory doesn't support decoding HEIF format, so we don't
// test that here. // test that format here.
return ImmutableList.of("png/non-motion-photo-shortened.png"); return ImmutableList.of(
"png/non-motion-photo-shortened.png", "jpeg/non-motion-photo-shortened.jpg");
} }
@Test @Test

View File

@ -153,6 +153,7 @@ public final class DefaultExtractorsFactory implements ExtractorsFactory {
private int tsTimestampSearchBytes; private int tsTimestampSearchBytes;
private boolean textTrackTranscodingEnabled; private boolean textTrackTranscodingEnabled;
private SubtitleParser.Factory subtitleParserFactory; private SubtitleParser.Factory subtitleParserFactory;
private @JpegExtractor.Flags int jpegFlags;
public DefaultExtractorsFactory() { public DefaultExtractorsFactory() {
tsMode = TsExtractor.MODE_SINGLE_PMT; tsMode = TsExtractor.MODE_SINGLE_PMT;
@ -391,6 +392,20 @@ public final class DefaultExtractorsFactory implements ExtractorsFactory {
return this; return this;
} }
/**
* Sets flags for {@link JpegExtractor} instances created by the factory.
*
* @see JpegExtractor#JpegExtractor(int)
* @param flags The flags to use.
* @return The factory, for convenience.
*/
@CanIgnoreReturnValue
public synchronized DefaultExtractorsFactory setJpegExtractorFlags(
@JpegExtractor.Flags int flags) {
this.jpegFlags = flags;
return this;
}
@Override @Override
public synchronized Extractor[] createExtractors() { public synchronized Extractor[] createExtractors() {
return createExtractors(Uri.EMPTY, new HashMap<>()); return createExtractors(Uri.EMPTY, new HashMap<>());
@ -509,7 +524,7 @@ public final class DefaultExtractorsFactory implements ExtractorsFactory {
extractors.add(new WavExtractor()); extractors.add(new WavExtractor());
break; break;
case FileTypes.JPEG: case FileTypes.JPEG:
extractors.add(new JpegExtractor()); extractors.add(new JpegExtractor(jpegFlags));
break; break;
case FileTypes.MIDI: case FileTypes.MIDI:
@Nullable Extractor midiExtractor = MIDI_EXTENSION_LOADER.getExtractor(); @Nullable Extractor midiExtractor = MIDI_EXTENSION_LOADER.getExtractor();

View File

@ -0,0 +1,5 @@
ImageOutput:
rendered image count = 1
image output #1:
presentationTimeUs = 0
bitmap hash = 1655078913