Check sampleMimeType rather than containerMimeType for images

These are often the same for image tracks, since we usually drop the
whole image file (both the container and actual encoded image bytes)
into a single sample, but there are cases where we emit a track with
`containerMimeType=image/jpeg` but **no** samples (from
`JpegMotionPhotoExtractor`, to carry some metadata about the image +
video byte offsets).

It's therefore more correct to implement the `supportsFormat` check
based on `sampleMimeType`, so that these 'empty' image tracks are not
considered 'supported' by `ImageRenderer`.

#minor-release

PiperOrigin-RevId: 604672331
This commit is contained in:
ibaker 2024-02-06 09:28:33 -08:00 committed by Copybara-Service
parent c2273345c5
commit eabba49610
16 changed files with 27 additions and 28 deletions

View File

@ -89,10 +89,10 @@ public final class BitmapFactoryImageDecoder
@Override @Override
public @RendererCapabilities.Capabilities int supportsFormat(Format format) { public @RendererCapabilities.Capabilities int supportsFormat(Format format) {
if (format.containerMimeType == null || !MimeTypes.isImage(format.containerMimeType)) { if (format.sampleMimeType == null || !MimeTypes.isImage(format.sampleMimeType)) {
return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE); return RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE);
} }
return isBitmapFactorySupportedMimeType(format.containerMimeType) return isBitmapFactorySupportedMimeType(format.sampleMimeType)
? RendererCapabilities.create(C.FORMAT_HANDLED) ? RendererCapabilities.create(C.FORMAT_HANDLED)
: RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE); : RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE);
} }

View File

@ -35,7 +35,7 @@ public class BitmapFactoryImageDecoderFactoryTest {
@Test @Test
public void supportsFormat_validFormat_returnsFormatSupported() throws Exception { public void supportsFormat_validFormat_returnsFormatSupported() throws Exception {
Format.Builder format = new Format.Builder().setContainerMimeType(MimeTypes.IMAGE_JPEG); Format.Builder format = new Format.Builder().setSampleMimeType(MimeTypes.IMAGE_JPEG);
assertThat(imageDecoderFactory.supportsFormat(format.build())) assertThat(imageDecoderFactory.supportsFormat(format.build()))
.isEqualTo(RendererCapabilities.create(C.FORMAT_HANDLED)); .isEqualTo(RendererCapabilities.create(C.FORMAT_HANDLED));
@ -53,7 +53,7 @@ public class BitmapFactoryImageDecoderFactoryTest {
public void supportsFormat_nonImageMimeType_returnsUnsupportedType() throws Exception { public void supportsFormat_nonImageMimeType_returnsUnsupportedType() throws Exception {
Format.Builder format = new Format.Builder(); Format.Builder format = new Format.Builder();
format.setContainerMimeType(MimeTypes.VIDEO_AV1); format.setSampleMimeType(MimeTypes.VIDEO_AV1);
assertThat(imageDecoderFactory.supportsFormat(format.build())) assertThat(imageDecoderFactory.supportsFormat(format.build()))
.isEqualTo(RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE)); .isEqualTo(RendererCapabilities.create(C.FORMAT_UNSUPPORTED_TYPE));
@ -63,7 +63,7 @@ public class BitmapFactoryImageDecoderFactoryTest {
public void supportsFormat_unsupportedImageMimeType_returnsUnsupportedSubType() throws Exception { public void supportsFormat_unsupportedImageMimeType_returnsUnsupportedSubType() throws Exception {
Format.Builder format = new Format.Builder(); Format.Builder format = new Format.Builder();
format.setContainerMimeType("image/custom"); format.setSampleMimeType("image/custom");
assertThat(imageDecoderFactory.supportsFormat(format.build())) assertThat(imageDecoderFactory.supportsFormat(format.build()))
.isEqualTo(RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE)); .isEqualTo(RendererCapabilities.create(C.FORMAT_UNSUPPORTED_SUBTYPE));

View File

@ -56,19 +56,19 @@ public class ImageRendererTest {
"Renderer has not read stream to end after " + DEFAULT_LOOP_TIMEOUT_MS + " milliseconds."; "Renderer has not read stream to end after " + DEFAULT_LOOP_TIMEOUT_MS + " milliseconds.";
private static final Format PNG_FORMAT = private static final Format PNG_FORMAT =
new Format.Builder() new Format.Builder()
.setContainerMimeType(MimeTypes.IMAGE_PNG) .setSampleMimeType(MimeTypes.IMAGE_PNG)
.setTileCountVertical(1) .setTileCountVertical(1)
.setTileCountHorizontal(1) .setTileCountHorizontal(1)
.build(); .build();
private static final Format JPEG_FORMAT = private static final Format JPEG_FORMAT =
new Format.Builder() new Format.Builder()
.setContainerMimeType(MimeTypes.IMAGE_JPEG) .setSampleMimeType(MimeTypes.IMAGE_JPEG)
.setTileCountVertical(1) .setTileCountVertical(1)
.setTileCountHorizontal(1) .setTileCountHorizontal(1)
.build(); .build();
private static final Format JPEG_FORMAT_WITH_FOUR_TILES = private static final Format JPEG_FORMAT_WITH_FOUR_TILES =
new Format.Builder() new Format.Builder()
.setContainerMimeType(MimeTypes.IMAGE_JPEG) .setSampleMimeType(MimeTypes.IMAGE_JPEG)
.setTileCountVertical(2) .setTileCountVertical(2)
.setTileCountHorizontal(2) .setTileCountHorizontal(2)
.build(); .build();

View File

@ -40,7 +40,7 @@ public final class SingleSampleExtractor implements Extractor {
private final int fileSignature; private final int fileSignature;
private final int fileSignatureLength; private final int fileSignatureLength;
private final String containerMimeType; private final String sampleMimeType;
/** Parser states. */ /** Parser states. */
@Documented @Documented
@ -72,13 +72,12 @@ public final class SingleSampleExtractor implements Extractor {
* method won't be used. * method won't be used.
* @param fileSignatureLength The length of file signature, or {@link C#LENGTH_UNSET} if the * @param fileSignatureLength The length of file signature, or {@link C#LENGTH_UNSET} if the
* {@link #sniff} method won't be used. * {@link #sniff} method won't be used.
* @param containerMimeType The mime type of the format being extracted. * @param sampleMimeType The mime type of the sample.
*/ */
public SingleSampleExtractor( public SingleSampleExtractor(int fileSignature, int fileSignatureLength, String sampleMimeType) {
int fileSignature, int fileSignatureLength, String containerMimeType) {
this.fileSignature = fileSignature; this.fileSignature = fileSignature;
this.fileSignatureLength = fileSignatureLength; this.fileSignatureLength = fileSignatureLength;
this.containerMimeType = containerMimeType; this.sampleMimeType = sampleMimeType;
} }
@Override @Override
@ -92,7 +91,7 @@ public final class SingleSampleExtractor implements Extractor {
@Override @Override
public void init(ExtractorOutput output) { public void init(ExtractorOutput output) {
extractorOutput = output; extractorOutput = output;
outputImageTrackAndSeekMap(containerMimeType); outputImageTrackAndSeekMap(sampleMimeType);
} }
@Override @Override
@ -137,9 +136,9 @@ public final class SingleSampleExtractor implements Extractor {
} }
@RequiresNonNull("this.extractorOutput") @RequiresNonNull("this.extractorOutput")
private void outputImageTrackAndSeekMap(String containerMimeType) { private void outputImageTrackAndSeekMap(String sampleMimeType) {
trackOutput = extractorOutput.track(IMAGE_TRACK_ID, C.TRACK_TYPE_IMAGE); trackOutput = extractorOutput.track(IMAGE_TRACK_ID, C.TRACK_TYPE_IMAGE);
trackOutput.format(new Format.Builder().setContainerMimeType(containerMimeType).build()); trackOutput.format(new Format.Builder().setSampleMimeType(sampleMimeType).build());
extractorOutput.endTracks(); extractorOutput.endTracks();
extractorOutput.seekMap(new SingleSampleSeekMap(/* durationUs= */ C.TIME_UNSET)); extractorOutput.seekMap(new SingleSampleSeekMap(/* durationUs= */ C.TIME_UNSET));
state = STATE_READING; state = STATE_READING;

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 69130 total output bytes = 69130
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/bmp sampleMimeType = image/bmp
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 69130 total output bytes = 69130
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/bmp sampleMimeType = image/bmp
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 57672 total output bytes = 57672
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/heif sampleMimeType = image/heif
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 57672 total output bytes = 57672
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/heif sampleMimeType = image/heif
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 30000 total output bytes = 30000
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/jpeg sampleMimeType = image/jpeg
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 30000 total output bytes = 30000
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/jpeg sampleMimeType = image/jpeg
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 140312 total output bytes = 140312
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/jpeg sampleMimeType = image/jpeg
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 140312 total output bytes = 140312
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/jpeg sampleMimeType = image/jpeg
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 29063 total output bytes = 29063
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/png sampleMimeType = image/png
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 29063 total output bytes = 29063
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/png sampleMimeType = image/png
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 7778 total output bytes = 7778
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/webp sampleMimeType = image/webp
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1

View File

@ -8,7 +8,7 @@ track 1024:
total output bytes = 7778 total output bytes = 7778
sample count = 1 sample count = 1
format 0: format 0:
containerMimeType = image/webp sampleMimeType = image/webp
sample 0: sample 0:
time = 0 time = 0
flags = 1 flags = 1