mirror of
https://github.com/androidx/media.git
synced 2025-05-04 22:20:47 +08:00
Added two new image specific properties 'tileCountHorizontal' and 'tileCountVertical' to class Format. DashManifestParser adjusted to parse these values from an EssentialProperty tag of an Image AdaptationSet. With this change, DashManifest does not have to do any parsing inside the new getThumbnailDescriptions() method. Moreover, both classes ThumbnailDescription and ThumbnailProvider adjusted to use these two properties / naming scheme accordingly.
This commit is contained in:
parent
158cf0c8ed
commit
2f8fd87fa2
@ -92,7 +92,7 @@ public class DefaultThumbnailProvider implements ThumbnailProvider {
|
||||
|
||||
if (position < thumbnailDescription.getStartTimeMs() || position > thumbnailDescription.getStartTimeMs() + thumbnailDescription.getDurationMs()) return null;
|
||||
|
||||
int count = thumbnailDescription.getColumns() * thumbnailDescription.getRows();
|
||||
int count = thumbnailDescription.getTileCountHorizontal() * thumbnailDescription.getTileCountVertical();
|
||||
|
||||
int durationPerImage = (int)(thumbnailDescription.getDurationMs() / count);
|
||||
|
||||
@ -101,12 +101,12 @@ public class DefaultThumbnailProvider implements ThumbnailProvider {
|
||||
//handle special case if position == duration
|
||||
if (imageNumberToUseWithinTile > count-1) imageNumberToUseWithinTile = count-1;
|
||||
|
||||
int intRowToUse = (int)(imageNumberToUseWithinTile / thumbnailDescription.getColumns());
|
||||
int intRowToUse = (int)(imageNumberToUseWithinTile / thumbnailDescription.getTileCountHorizontal());
|
||||
|
||||
int intColToUse = imageNumberToUseWithinTile - intRowToUse * thumbnailDescription.getColumns();
|
||||
int intColToUse = imageNumberToUseWithinTile - intRowToUse * thumbnailDescription.getTileCountHorizontal();
|
||||
|
||||
double thumbnailWidth = (double) thumbnailDescription.getImageWidth() / thumbnailDescription.getColumns();
|
||||
double thumbnailHeight = (double) thumbnailDescription.getImageHeight() / thumbnailDescription.getRows();
|
||||
double thumbnailWidth = (double) thumbnailDescription.getImageWidth() / thumbnailDescription.getTileCountHorizontal();
|
||||
double thumbnailHeight = (double) thumbnailDescription.getImageHeight() / thumbnailDescription.getTileCountVertical();
|
||||
|
||||
int cropXLeft = (int)Math.round(intColToUse * thumbnailWidth);
|
||||
int cropYTop = (int)Math.round(intRowToUse * thumbnailHeight);
|
||||
|
@ -115,6 +115,13 @@ import java.util.UUID;
|
||||
* <ul>
|
||||
* <li>{@link #accessibilityChannel}
|
||||
* </ul>
|
||||
*
|
||||
* <h2 id="image-formats">Fields relevant to image formats</h2>
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link #tileCountHorizontal}
|
||||
* <li>{@link #tileCountVertical}
|
||||
* </ul>
|
||||
*/
|
||||
public final class Format implements Bundleable {
|
||||
|
||||
@ -174,6 +181,11 @@ public final class Format implements Bundleable {
|
||||
|
||||
private int accessibilityChannel;
|
||||
|
||||
// Image specific
|
||||
|
||||
private int tileCountHorizontal;
|
||||
private int tileCountVertical;
|
||||
|
||||
// Provided by the source.
|
||||
|
||||
private @C.CryptoType int cryptoType;
|
||||
@ -197,6 +209,9 @@ public final class Format implements Bundleable {
|
||||
pcmEncoding = NO_VALUE;
|
||||
// Text specific.
|
||||
accessibilityChannel = NO_VALUE;
|
||||
// Image specific.
|
||||
tileCountHorizontal = NO_VALUE;
|
||||
tileCountVertical = NO_VALUE;
|
||||
// Provided by the source.
|
||||
cryptoType = C.CRYPTO_TYPE_NONE;
|
||||
}
|
||||
@ -241,6 +256,9 @@ public final class Format implements Bundleable {
|
||||
this.encoderPadding = format.encoderPadding;
|
||||
// Text specific.
|
||||
this.accessibilityChannel = format.accessibilityChannel;
|
||||
// Image specific.
|
||||
this.tileCountHorizontal = format.tileCountHorizontal;
|
||||
this.tileCountVertical = format.tileCountVertical;
|
||||
// Provided by the source.
|
||||
this.cryptoType = format.cryptoType;
|
||||
}
|
||||
@ -616,6 +634,30 @@ public final class Format implements Bundleable {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Image specific.
|
||||
|
||||
/**
|
||||
* Sets {@link Format#tileCountHorizontal}. The default value is {@link #NO_VALUE}.
|
||||
*
|
||||
* @param tileCountHorizontal The {@link Format#accessibilityChannel}.
|
||||
* @return The builder.
|
||||
*/
|
||||
public Builder setTileCountHorizontal(int tileCountHorizontal) {
|
||||
this.tileCountHorizontal = tileCountHorizontal;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@link Format#tileCountVertical}. The default value is {@link #NO_VALUE}.
|
||||
*
|
||||
* @param tileCountVertical The {@link Format#accessibilityChannel}.
|
||||
* @return The builder.
|
||||
*/
|
||||
public Builder setTileCountVertical(int tileCountVertical) {
|
||||
this.tileCountVertical = tileCountVertical;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Provided by source.
|
||||
|
||||
/**
|
||||
@ -788,6 +830,12 @@ public final class Format implements Bundleable {
|
||||
/** The Accessibility channel, or {@link #NO_VALUE} if not known or applicable. */
|
||||
public final int accessibilityChannel;
|
||||
|
||||
// Image specific.
|
||||
|
||||
/** Thumbnail tile count horizontal and vertical, or {@link #NO_VALUE} if not known or applicable. */
|
||||
public final int tileCountHorizontal;
|
||||
public final int tileCountVertical;
|
||||
|
||||
// Provided by source.
|
||||
|
||||
/**
|
||||
@ -1011,6 +1059,9 @@ public final class Format implements Bundleable {
|
||||
encoderPadding = builder.encoderPadding == NO_VALUE ? 0 : builder.encoderPadding;
|
||||
// Text specific.
|
||||
accessibilityChannel = builder.accessibilityChannel;
|
||||
// Image specific.
|
||||
tileCountHorizontal = builder.tileCountHorizontal;
|
||||
tileCountVertical = builder.tileCountVertical;
|
||||
// Provided by source.
|
||||
if (builder.cryptoType == C.CRYPTO_TYPE_NONE && drmInitData != null) {
|
||||
// Encrypted content cannot use CRYPTO_TYPE_NONE.
|
||||
@ -1257,6 +1308,9 @@ public final class Format implements Bundleable {
|
||||
result = 31 * result + encoderPadding;
|
||||
// Text specific.
|
||||
result = 31 * result + accessibilityChannel;
|
||||
// Image specific.
|
||||
result = 31 * result + tileCountHorizontal;
|
||||
result = 31 * result + tileCountVertical;
|
||||
// Provided by the source.
|
||||
result = 31 * result + cryptoType;
|
||||
hashCode = result;
|
||||
@ -1293,6 +1347,8 @@ public final class Format implements Bundleable {
|
||||
&& encoderDelay == other.encoderDelay
|
||||
&& encoderPadding == other.encoderPadding
|
||||
&& accessibilityChannel == other.accessibilityChannel
|
||||
&& tileCountHorizontal == other.tileCountHorizontal
|
||||
&& tileCountVertical == other.tileCountVertical
|
||||
&& cryptoType == other.cryptoType
|
||||
&& Float.compare(frameRate, other.frameRate) == 0
|
||||
&& Float.compare(pixelWidthHeightRatio, other.pixelWidthHeightRatio) == 0
|
||||
@ -1490,6 +1546,8 @@ public final class Format implements Bundleable {
|
||||
FIELD_ENCODER_PADDING,
|
||||
FIELD_ACCESSIBILITY_CHANNEL,
|
||||
FIELD_CRYPTO_TYPE,
|
||||
FIELD_TILE_COUNT_HORIZONTAL,
|
||||
FIELD_TILE_COUNT_VERTICAL,
|
||||
})
|
||||
private @interface FieldNumber {}
|
||||
|
||||
@ -1523,6 +1581,8 @@ public final class Format implements Bundleable {
|
||||
private static final int FIELD_ENCODER_PADDING = 27;
|
||||
private static final int FIELD_ACCESSIBILITY_CHANNEL = 28;
|
||||
private static final int FIELD_CRYPTO_TYPE = 29;
|
||||
private static final int FIELD_TILE_COUNT_HORIZONTAL = 30;
|
||||
private static final int FIELD_TILE_COUNT_VERTICAL = 31;
|
||||
|
||||
@Override
|
||||
public Bundle toBundle() {
|
||||
@ -1578,6 +1638,9 @@ public final class Format implements Bundleable {
|
||||
bundle.putInt(keyForField(FIELD_ENCODER_PADDING), encoderPadding);
|
||||
// Text specific.
|
||||
bundle.putInt(keyForField(FIELD_ACCESSIBILITY_CHANNEL), accessibilityChannel);
|
||||
// Image specific.
|
||||
bundle.putInt(keyForField(FIELD_TILE_COUNT_HORIZONTAL), tileCountHorizontal);
|
||||
bundle.putInt(keyForField(FIELD_TILE_COUNT_VERTICAL), tileCountVertical);
|
||||
// Source specific.
|
||||
bundle.putInt(keyForField(FIELD_CRYPTO_TYPE), cryptoType);
|
||||
return bundle;
|
||||
@ -1652,6 +1715,11 @@ public final class Format implements Bundleable {
|
||||
// Text specific.
|
||||
.setAccessibilityChannel(
|
||||
bundle.getInt(keyForField(FIELD_ACCESSIBILITY_CHANNEL), DEFAULT.accessibilityChannel))
|
||||
// Image specific.
|
||||
.setTileCountHorizontal(
|
||||
bundle.getInt(keyForField(FIELD_TILE_COUNT_HORIZONTAL), DEFAULT.tileCountHorizontal))
|
||||
.setTileCountVertical(
|
||||
bundle.getInt(keyForField(FIELD_TILE_COUNT_VERTICAL), DEFAULT.tileCountVertical))
|
||||
// Source specific.
|
||||
.setCryptoType(bundle.getInt(keyForField(FIELD_CRYPTO_TYPE), DEFAULT.cryptoType));
|
||||
|
||||
|
@ -7,19 +7,19 @@ public class ThumbnailDescription {
|
||||
private final String id;
|
||||
private final Uri uri;
|
||||
private final int bitrate;
|
||||
private final int rows;
|
||||
private final int columns;
|
||||
private final int tileCountHorizontal;
|
||||
private final int tileCountVertical;
|
||||
private final long startTimeMs;
|
||||
private final long durationMs;
|
||||
private final int imageWidth; // Image width (Pixel)
|
||||
private final int imageHeight; // Image height (Pixel)
|
||||
|
||||
public ThumbnailDescription(String id, Uri uri, int bitrate, int rows, int columns, long startTimeMs, long durationMs, int imageWidth, int imageHeight) {
|
||||
public ThumbnailDescription(String id, Uri uri, int bitrate, int tileCountHorizontal, int tileCountVertical, long startTimeMs, long durationMs, int imageWidth, int imageHeight) {
|
||||
this.id = id;
|
||||
this.uri = uri;
|
||||
this.bitrate = bitrate;
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
this.tileCountHorizontal = tileCountHorizontal;
|
||||
this.tileCountVertical = tileCountVertical;
|
||||
this.startTimeMs = startTimeMs;
|
||||
this.durationMs = durationMs;
|
||||
this.imageWidth = imageWidth;
|
||||
@ -34,12 +34,12 @@ public class ThumbnailDescription {
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
public int getRows() {
|
||||
return rows;
|
||||
public int getTileCountHorizontal() {
|
||||
return tileCountHorizontal;
|
||||
}
|
||||
|
||||
public int getColumns() {
|
||||
return columns;
|
||||
public int getTileCountVertical() {
|
||||
return tileCountVertical;
|
||||
}
|
||||
|
||||
public long getStartTimeMs() {
|
||||
|
@ -185,22 +185,9 @@ public class DashManifest implements FilterableManifest<DashManifest> {
|
||||
int bitrate = representation.format.bitrate;
|
||||
int imageWidth = representation.format.width;
|
||||
int imageHeight = representation.format.height;
|
||||
|
||||
// get size XxY, e.g. 10x20, where 10 is column count and 20 is row count
|
||||
int rows = 1;
|
||||
int cols = 1;
|
||||
for (int m = 0; m < representation.essentialProperties.size(); m++) {
|
||||
Descriptor descriptor = representation.essentialProperties.get(m);
|
||||
if ((Ascii.equalsIgnoreCase("http://dashif.org/thumbnail_tile", descriptor.schemeIdUri) || Ascii.equalsIgnoreCase("http://dashif.org/guidelines/thumbnail_tile", descriptor.schemeIdUri)) && descriptor.value != null) {
|
||||
String size = descriptor.value;
|
||||
String[] sizeSplit = size.split("x");
|
||||
if (sizeSplit.length != 2) {
|
||||
continue;
|
||||
}
|
||||
cols = Integer.parseInt(sizeSplit[0]);
|
||||
rows = Integer.parseInt(sizeSplit[1]);
|
||||
}
|
||||
}
|
||||
int tileCountHorizontal = representation.format.tileCountHorizontal;
|
||||
int tileCountVertical = representation.format.tileCountVertical;
|
||||
|
||||
long now = Util.getNowUnixTimeMs(C.TIME_UNSET);
|
||||
String baseUrl = castNonNull(baseUrlExclusionList.selectBaseUrl(representation.baseUrls)).url;
|
||||
@ -217,7 +204,7 @@ public class DashManifest implements FilterableManifest<DashManifest> {
|
||||
RangedUri rangedUri = index.getSegmentUrl(segmentNumber);
|
||||
DataSpec dataSpec = DashUtil.buildDataSpec(representation, baseUrl, rangedUri, /* flags= */ 0);
|
||||
Uri uri = dataSpec.uri;
|
||||
ThumbnailDescription thumbnailDescription = new ThumbnailDescription(id, uri, bitrate, rows, cols, Util.usToMs(segmentStartTimeUs - (dynamic ? firstStartTimeUs : 0)), Util.usToMs(segmentDurationUs), imageWidth, imageHeight);
|
||||
ThumbnailDescription thumbnailDescription = new ThumbnailDescription(id, uri, bitrate, tileCountHorizontal, tileCountVertical, Util.usToMs(segmentStartTimeUs - (dynamic ? firstStartTimeUs : 0)), Util.usToMs(segmentDurationUs), imageWidth, imageHeight);
|
||||
thumbnailDescriptions.add(thumbnailDescription);
|
||||
}
|
||||
}
|
||||
|
@ -811,6 +811,8 @@ public class DashManifestParser extends DefaultHandler
|
||||
roleFlags |= parseRoleFlagsFromProperties(essentialProperties);
|
||||
roleFlags |= parseRoleFlagsFromProperties(supplementalProperties);
|
||||
|
||||
Pair<Integer,Integer> tileCounts = parseTileCountFromProperties(essentialProperties);
|
||||
|
||||
Format.Builder formatBuilder =
|
||||
new Format.Builder()
|
||||
.setId(id)
|
||||
@ -820,7 +822,9 @@ public class DashManifestParser extends DefaultHandler
|
||||
.setPeakBitrate(bitrate)
|
||||
.setSelectionFlags(selectionFlags)
|
||||
.setRoleFlags(roleFlags)
|
||||
.setLanguage(language);
|
||||
.setLanguage(language)
|
||||
.setTileCountHorizontal(tileCounts != null ? tileCounts.first : Format.NO_VALUE)
|
||||
.setTileCountVertical(tileCounts != null ? tileCounts.second : Format.NO_VALUE);
|
||||
|
||||
if (MimeTypes.isVideo(sampleMimeType)) {
|
||||
formatBuilder.setWidth(width).setHeight(height).setFrameRate(frameRate);
|
||||
@ -1629,6 +1633,31 @@ public class DashManifestParser extends DefaultHandler
|
||||
return attributeValue.split(",");
|
||||
}
|
||||
|
||||
// Thumbnail tile information parsing
|
||||
|
||||
/**
|
||||
* Parses given descriptors for thumbnail tile information
|
||||
* @param essentialProperties List of descriptor that contain thumbnail tile information
|
||||
* @return A pair of Integer values, where the first is the count of horizontal tiles
|
||||
* and the second is the count of vertical tiles, or null if no thumbnail tile information is found.
|
||||
*/
|
||||
@Nullable
|
||||
protected Pair<Integer,Integer> parseTileCountFromProperties(List<Descriptor> essentialProperties) {
|
||||
for (Descriptor descriptor : essentialProperties) {
|
||||
if ((Ascii.equalsIgnoreCase("http://dashif.org/thumbnail_tile", descriptor.schemeIdUri) || Ascii.equalsIgnoreCase("http://dashif.org/guidelines/thumbnail_tile", descriptor.schemeIdUri)) && descriptor.value != null) {
|
||||
String size = descriptor.value;
|
||||
String[] sizeSplit = size.split("x");
|
||||
if (sizeSplit.length != 2) {
|
||||
continue;
|
||||
}
|
||||
int tileCountHorizontal = Integer.parseInt(sizeSplit[0]);
|
||||
int tileCountVertical = Integer.parseInt(sizeSplit[1]);
|
||||
return Pair.create(tileCountHorizontal, tileCountVertical);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Utility methods.
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user