1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.google.android.exoplayer2; 17 18 import android.os.Parcel; 19 import android.os.Parcelable; 20 import androidx.annotation.Nullable; 21 import com.google.android.exoplayer2.drm.DrmInitData; 22 import com.google.android.exoplayer2.drm.ExoMediaCrypto; 23 import com.google.android.exoplayer2.metadata.Metadata; 24 import com.google.android.exoplayer2.util.MimeTypes; 25 import com.google.android.exoplayer2.util.Util; 26 import com.google.android.exoplayer2.video.ColorInfo; 27 import java.util.ArrayList; 28 import java.util.Arrays; 29 import java.util.Collections; 30 import java.util.List; 31 32 /** 33 * Represents a media format. 34 * 35 * <p>When building formats, populate all fields whose values are known and relevant to the type of 36 * format being constructed. For information about different types of format, see ExoPlayer's <a 37 * href="https://exoplayer.dev/supported-formats.html">Supported formats page</a>. 38 * 39 * <h3>Fields commonly relevant to all formats</h3> 40 * 41 * <ul> 42 * <li>{@link #id} 43 * <li>{@link #label} 44 * <li>{@link #language} 45 * <li>{@link #selectionFlags} 46 * <li>{@link #roleFlags} 47 * <li>{@link #averageBitrate} 48 * <li>{@link #peakBitrate} 49 * <li>{@link #codecs} 50 * <li>{@link #metadata} 51 * </ul> 52 * 53 * <h3 id="container-formats">Fields relevant to container formats</h3> 54 * 55 * <ul> 56 * <li>{@link #containerMimeType} 57 * <li>If the container only contains a single media track, <a href="#sample-formats">fields 58 * relevant to sample formats</a> can are also be relevant and can be set to describe the 59 * sample format of that track. 60 * <li>If the container only contains one track of a given type (possibly alongside tracks of 61 * other types), then fields relevant to that track type can be set to describe the properties 62 * of the track. See the sections below for <a href="#video-formats">video</a>, <a 63 * href="#audio-formats">audio</a> and <a href="#text-formats">text</a> formats. 64 * </ul> 65 * 66 * <h3 id="sample-formats">Fields relevant to sample formats</h3> 67 * 68 * <ul> 69 * <li>{@link #sampleMimeType} 70 * <li>{@link #maxInputSize} 71 * <li>{@link #initializationData} 72 * <li>{@link #drmInitData} 73 * <li>{@link #subsampleOffsetUs} 74 * <li>Fields relevant to the sample format's track type are also relevant. See the sections below 75 * for <a href="#video-formats">video</a>, <a href="#audio-formats">audio</a> and <a 76 * href="#text-formats">text</a> formats. 77 * </ul> 78 * 79 * <h3 id="video-formats">Fields relevant to video formats</h3> 80 * 81 * <ul> 82 * <li>{@link #width} 83 * <li>{@link #height} 84 * <li>{@link #frameRate} 85 * <li>{@link #rotationDegrees} 86 * <li>{@link #pixelWidthHeightRatio} 87 * <li>{@link #projectionData} 88 * <li>{@link #stereoMode} 89 * <li>{@link #colorInfo} 90 * </ul> 91 * 92 * <h3 id="audio-formats">Fields relevant to audio formats</h3> 93 * 94 * <ul> 95 * <li>{@link #channelCount} 96 * <li>{@link #sampleRate} 97 * <li>{@link #pcmEncoding} 98 * <li>{@link #encoderDelay} 99 * <li>{@link #encoderPadding} 100 * </ul> 101 * 102 * <h3 id="text-formats">Fields relevant to text formats</h3> 103 * 104 * <ul> 105 * <li>{@link #accessibilityChannel} 106 * </ul> 107 */ 108 public final class Format implements Parcelable { 109 110 /** 111 * Builds {@link Format} instances. 112 * 113 * <p>Use Format#buildUpon() to obtain a builder representing an existing {@link Format}. 114 * 115 * <p>When building formats, populate all fields whose values are known and relevant to the type 116 * of format being constructed. See the {@link Format} Javadoc for information about which fields 117 * should be set for different types of format. 118 */ 119 public static final class Builder { 120 121 @Nullable private String id; 122 @Nullable private String label; 123 @Nullable private String language; 124 @C.SelectionFlags private int selectionFlags; 125 @C.RoleFlags private int roleFlags; 126 private int averageBitrate; 127 private int peakBitrate; 128 @Nullable private String codecs; 129 @Nullable private Metadata metadata; 130 131 // Container specific. 132 133 @Nullable private String containerMimeType; 134 135 // Sample specific. 136 137 @Nullable private String sampleMimeType; 138 private int maxInputSize; 139 @Nullable private List<byte[]> initializationData; 140 @Nullable private DrmInitData drmInitData; 141 private long subsampleOffsetUs; 142 143 // Video specific. 144 145 private int width; 146 private int height; 147 private float frameRate; 148 private int rotationDegrees; 149 private float pixelWidthHeightRatio; 150 @Nullable private byte[] projectionData; 151 @C.StereoMode private int stereoMode; 152 @Nullable private ColorInfo colorInfo; 153 154 // Audio specific. 155 156 private int channelCount; 157 private int sampleRate; 158 @C.PcmEncoding private int pcmEncoding; 159 private int encoderDelay; 160 private int encoderPadding; 161 162 // Text specific. 163 164 private int accessibilityChannel; 165 166 // Provided by source. 167 168 @Nullable private Class<? extends ExoMediaCrypto> exoMediaCryptoType; 169 170 /** Creates a new instance with default values. */ Builder()171 public Builder() { 172 averageBitrate = NO_VALUE; 173 peakBitrate = NO_VALUE; 174 // Sample specific. 175 maxInputSize = NO_VALUE; 176 subsampleOffsetUs = OFFSET_SAMPLE_RELATIVE; 177 // Video specific. 178 width = NO_VALUE; 179 height = NO_VALUE; 180 frameRate = NO_VALUE; 181 pixelWidthHeightRatio = 1.0f; 182 stereoMode = NO_VALUE; 183 // Audio specific. 184 channelCount = NO_VALUE; 185 sampleRate = NO_VALUE; 186 pcmEncoding = NO_VALUE; 187 // Text specific. 188 accessibilityChannel = NO_VALUE; 189 } 190 191 /** 192 * Creates a new instance to build upon the provided {@link Format}. 193 * 194 * @param format The {@link Format} to build upon. 195 */ Builder(Format format)196 private Builder(Format format) { 197 this.id = format.id; 198 this.label = format.label; 199 this.language = format.language; 200 this.selectionFlags = format.selectionFlags; 201 this.roleFlags = format.roleFlags; 202 this.averageBitrate = format.averageBitrate; 203 this.peakBitrate = format.peakBitrate; 204 this.codecs = format.codecs; 205 this.metadata = format.metadata; 206 // Container specific. 207 this.containerMimeType = format.containerMimeType; 208 // Sample specific. 209 this.sampleMimeType = format.sampleMimeType; 210 this.maxInputSize = format.maxInputSize; 211 this.initializationData = format.initializationData; 212 this.drmInitData = format.drmInitData; 213 this.subsampleOffsetUs = format.subsampleOffsetUs; 214 // Video specific. 215 this.width = format.width; 216 this.height = format.height; 217 this.frameRate = format.frameRate; 218 this.rotationDegrees = format.rotationDegrees; 219 this.pixelWidthHeightRatio = format.pixelWidthHeightRatio; 220 this.projectionData = format.projectionData; 221 this.stereoMode = format.stereoMode; 222 this.colorInfo = format.colorInfo; 223 // Audio specific. 224 this.channelCount = format.channelCount; 225 this.sampleRate = format.sampleRate; 226 this.pcmEncoding = format.pcmEncoding; 227 this.encoderDelay = format.encoderDelay; 228 this.encoderPadding = format.encoderPadding; 229 // Text specific. 230 this.accessibilityChannel = format.accessibilityChannel; 231 // Provided by source. 232 this.exoMediaCryptoType = format.exoMediaCryptoType; 233 } 234 235 /** 236 * Sets {@link Format#id}. The default value is {@code null}. 237 * 238 * @param id The {@link Format#id}. 239 * @return The builder. 240 */ setId(@ullable String id)241 public Builder setId(@Nullable String id) { 242 this.id = id; 243 return this; 244 } 245 246 /** 247 * Sets {@link Format#id} to {@link Integer#toString() Integer.toString(id)}. The default value 248 * is {@code null}. 249 * 250 * @param id The {@link Format#id}. 251 * @return The builder. 252 */ setId(int id)253 public Builder setId(int id) { 254 this.id = Integer.toString(id); 255 return this; 256 } 257 258 /** 259 * Sets {@link Format#label}. The default value is {@code null}. 260 * 261 * @param label The {@link Format#label}. 262 * @return The builder. 263 */ setLabel(@ullable String label)264 public Builder setLabel(@Nullable String label) { 265 this.label = label; 266 return this; 267 } 268 269 /** 270 * Sets {@link Format#language}. The default value is {@code null}. 271 * 272 * @param language The {@link Format#language}. 273 * @return The builder. 274 */ setLanguage(@ullable String language)275 public Builder setLanguage(@Nullable String language) { 276 this.language = language; 277 return this; 278 } 279 280 /** 281 * Sets {@link Format#selectionFlags}. The default value is 0. 282 * 283 * @param selectionFlags The {@link Format#selectionFlags}. 284 * @return The builder. 285 */ setSelectionFlags(@.SelectionFlags int selectionFlags)286 public Builder setSelectionFlags(@C.SelectionFlags int selectionFlags) { 287 this.selectionFlags = selectionFlags; 288 return this; 289 } 290 291 /** 292 * Sets {@link Format#roleFlags}. The default value is 0. 293 * 294 * @param roleFlags The {@link Format#roleFlags}. 295 * @return The builder. 296 */ setRoleFlags(@.RoleFlags int roleFlags)297 public Builder setRoleFlags(@C.RoleFlags int roleFlags) { 298 this.roleFlags = roleFlags; 299 return this; 300 } 301 302 /** 303 * Sets {@link Format#averageBitrate}. The default value is {@link #NO_VALUE}. 304 * 305 * @param averageBitrate The {@link Format#averageBitrate}. 306 * @return The builder. 307 */ setAverageBitrate(int averageBitrate)308 public Builder setAverageBitrate(int averageBitrate) { 309 this.averageBitrate = averageBitrate; 310 return this; 311 } 312 313 /** 314 * Sets {@link Format#peakBitrate}. The default value is {@link #NO_VALUE}. 315 * 316 * @param peakBitrate The {@link Format#peakBitrate}. 317 * @return The builder. 318 */ setPeakBitrate(int peakBitrate)319 public Builder setPeakBitrate(int peakBitrate) { 320 this.peakBitrate = peakBitrate; 321 return this; 322 } 323 324 /** 325 * Sets {@link Format#codecs}. The default value is {@code null}. 326 * 327 * @param codecs The {@link Format#codecs}. 328 * @return The builder. 329 */ setCodecs(@ullable String codecs)330 public Builder setCodecs(@Nullable String codecs) { 331 this.codecs = codecs; 332 return this; 333 } 334 335 /** 336 * Sets {@link Format#metadata}. The default value is {@code null}. 337 * 338 * @param metadata The {@link Format#metadata}. 339 * @return The builder. 340 */ setMetadata(@ullable Metadata metadata)341 public Builder setMetadata(@Nullable Metadata metadata) { 342 this.metadata = metadata; 343 return this; 344 } 345 346 // Container specific. 347 348 /** 349 * Sets {@link Format#containerMimeType}. The default value is {@code null}. 350 * 351 * @param containerMimeType The {@link Format#containerMimeType}. 352 * @return The builder. 353 */ setContainerMimeType(@ullable String containerMimeType)354 public Builder setContainerMimeType(@Nullable String containerMimeType) { 355 this.containerMimeType = containerMimeType; 356 return this; 357 } 358 359 // Sample specific. 360 361 /** 362 * Sets {@link Format#sampleMimeType}. The default value is {@code null}. 363 * 364 * @param sampleMimeType {@link Format#sampleMimeType}. 365 * @return The builder. 366 */ setSampleMimeType(@ullable String sampleMimeType)367 public Builder setSampleMimeType(@Nullable String sampleMimeType) { 368 this.sampleMimeType = sampleMimeType; 369 return this; 370 } 371 372 /** 373 * Sets {@link Format#maxInputSize}. The default value is {@link #NO_VALUE}. 374 * 375 * @param maxInputSize The {@link Format#maxInputSize}. 376 * @return The builder. 377 */ setMaxInputSize(int maxInputSize)378 public Builder setMaxInputSize(int maxInputSize) { 379 this.maxInputSize = maxInputSize; 380 return this; 381 } 382 383 /** 384 * Sets {@link Format#initializationData}. The default value is {@code null}. 385 * 386 * @param initializationData The {@link Format#initializationData}. 387 * @return The builder. 388 */ setInitializationData(@ullable List<byte[]> initializationData)389 public Builder setInitializationData(@Nullable List<byte[]> initializationData) { 390 this.initializationData = initializationData; 391 return this; 392 } 393 394 /** 395 * Sets {@link Format#drmInitData}. The default value is {@code null}. 396 * 397 * @param drmInitData The {@link Format#drmInitData}. 398 * @return The builder. 399 */ setDrmInitData(@ullable DrmInitData drmInitData)400 public Builder setDrmInitData(@Nullable DrmInitData drmInitData) { 401 this.drmInitData = drmInitData; 402 return this; 403 } 404 405 /** 406 * Sets {@link Format#subsampleOffsetUs}. The default value is {@link #OFFSET_SAMPLE_RELATIVE}. 407 * 408 * @param subsampleOffsetUs The {@link Format#subsampleOffsetUs}. 409 * @return The builder. 410 */ setSubsampleOffsetUs(long subsampleOffsetUs)411 public Builder setSubsampleOffsetUs(long subsampleOffsetUs) { 412 this.subsampleOffsetUs = subsampleOffsetUs; 413 return this; 414 } 415 416 // Video specific. 417 418 /** 419 * Sets {@link Format#width}. The default value is {@link #NO_VALUE}. 420 * 421 * @param width The {@link Format#width}. 422 * @return The builder. 423 */ setWidth(int width)424 public Builder setWidth(int width) { 425 this.width = width; 426 return this; 427 } 428 429 /** 430 * Sets {@link Format#height}. The default value is {@link #NO_VALUE}. 431 * 432 * @param height The {@link Format#height}. 433 * @return The builder. 434 */ setHeight(int height)435 public Builder setHeight(int height) { 436 this.height = height; 437 return this; 438 } 439 440 /** 441 * Sets {@link Format#frameRate}. The default value is {@link #NO_VALUE}. 442 * 443 * @param frameRate The {@link Format#frameRate}. 444 * @return The builder. 445 */ setFrameRate(float frameRate)446 public Builder setFrameRate(float frameRate) { 447 this.frameRate = frameRate; 448 return this; 449 } 450 451 /** 452 * Sets {@link Format#rotationDegrees}. The default value is 0. 453 * 454 * @param rotationDegrees The {@link Format#rotationDegrees}. 455 * @return The builder. 456 */ setRotationDegrees(int rotationDegrees)457 public Builder setRotationDegrees(int rotationDegrees) { 458 this.rotationDegrees = rotationDegrees; 459 return this; 460 } 461 462 /** 463 * Sets {@link Format#pixelWidthHeightRatio}. The default value is 1.0f. 464 * 465 * @param pixelWidthHeightRatio The {@link Format#pixelWidthHeightRatio}. 466 * @return The builder. 467 */ setPixelWidthHeightRatio(float pixelWidthHeightRatio)468 public Builder setPixelWidthHeightRatio(float pixelWidthHeightRatio) { 469 this.pixelWidthHeightRatio = pixelWidthHeightRatio; 470 return this; 471 } 472 473 /** 474 * Sets {@link Format#projectionData}. The default value is {@code null}. 475 * 476 * @param projectionData The {@link Format#projectionData}. 477 * @return The builder. 478 */ setProjectionData(@ullable byte[] projectionData)479 public Builder setProjectionData(@Nullable byte[] projectionData) { 480 this.projectionData = projectionData; 481 return this; 482 } 483 484 /** 485 * Sets {@link Format#stereoMode}. The default value is {@link #NO_VALUE}. 486 * 487 * @param stereoMode The {@link Format#stereoMode}. 488 * @return The builder. 489 */ setStereoMode(@.StereoMode int stereoMode)490 public Builder setStereoMode(@C.StereoMode int stereoMode) { 491 this.stereoMode = stereoMode; 492 return this; 493 } 494 495 /** 496 * Sets {@link Format#colorInfo}. The default value is {@code null}. 497 * 498 * @param colorInfo The {@link Format#colorInfo}. 499 * @return The builder. 500 */ setColorInfo(@ullable ColorInfo colorInfo)501 public Builder setColorInfo(@Nullable ColorInfo colorInfo) { 502 this.colorInfo = colorInfo; 503 return this; 504 } 505 506 // Audio specific. 507 508 /** 509 * Sets {@link Format#channelCount}. The default value is {@link #NO_VALUE}. 510 * 511 * @param channelCount The {@link Format#channelCount}. 512 * @return The builder. 513 */ setChannelCount(int channelCount)514 public Builder setChannelCount(int channelCount) { 515 this.channelCount = channelCount; 516 return this; 517 } 518 519 /** 520 * Sets {@link Format#sampleRate}. The default value is {@link #NO_VALUE}. 521 * 522 * @param sampleRate The {@link Format#sampleRate}. 523 * @return The builder. 524 */ setSampleRate(int sampleRate)525 public Builder setSampleRate(int sampleRate) { 526 this.sampleRate = sampleRate; 527 return this; 528 } 529 530 /** 531 * Sets {@link Format#pcmEncoding}. The default value is {@link #NO_VALUE}. 532 * 533 * @param pcmEncoding The {@link Format#pcmEncoding}. 534 * @return The builder. 535 */ setPcmEncoding(@.PcmEncoding int pcmEncoding)536 public Builder setPcmEncoding(@C.PcmEncoding int pcmEncoding) { 537 this.pcmEncoding = pcmEncoding; 538 return this; 539 } 540 541 /** 542 * Sets {@link Format#encoderDelay}. The default value is 0. 543 * 544 * @param encoderDelay The {@link Format#encoderDelay}. 545 * @return The builder. 546 */ setEncoderDelay(int encoderDelay)547 public Builder setEncoderDelay(int encoderDelay) { 548 this.encoderDelay = encoderDelay; 549 return this; 550 } 551 552 /** 553 * Sets {@link Format#encoderPadding}. The default value is 0. 554 * 555 * @param encoderPadding The {@link Format#encoderPadding}. 556 * @return The builder. 557 */ setEncoderPadding(int encoderPadding)558 public Builder setEncoderPadding(int encoderPadding) { 559 this.encoderPadding = encoderPadding; 560 return this; 561 } 562 563 // Text specific. 564 565 /** 566 * Sets {@link Format#accessibilityChannel}. The default value is {@link #NO_VALUE}. 567 * 568 * @param accessibilityChannel The {@link Format#accessibilityChannel}. 569 * @return The builder. 570 */ setAccessibilityChannel(int accessibilityChannel)571 public Builder setAccessibilityChannel(int accessibilityChannel) { 572 this.accessibilityChannel = accessibilityChannel; 573 return this; 574 } 575 576 // Provided by source. 577 578 /** 579 * Sets {@link Format#exoMediaCryptoType}. The default value is {@code null}. 580 * 581 * @param exoMediaCryptoType The {@link Format#exoMediaCryptoType}. 582 * @return The builder. 583 */ setExoMediaCryptoType( @ullable Class<? extends ExoMediaCrypto> exoMediaCryptoType)584 public Builder setExoMediaCryptoType( 585 @Nullable Class<? extends ExoMediaCrypto> exoMediaCryptoType) { 586 this.exoMediaCryptoType = exoMediaCryptoType; 587 return this; 588 } 589 590 // Build. 591 build()592 public Format build() { 593 return new Format( 594 id, 595 label, 596 language, 597 selectionFlags, 598 roleFlags, 599 averageBitrate, 600 peakBitrate, 601 codecs, 602 metadata, 603 containerMimeType, 604 sampleMimeType, 605 maxInputSize, 606 initializationData, 607 drmInitData, 608 subsampleOffsetUs, 609 width, 610 height, 611 frameRate, 612 rotationDegrees, 613 pixelWidthHeightRatio, 614 projectionData, 615 stereoMode, 616 colorInfo, 617 channelCount, 618 sampleRate, 619 pcmEncoding, 620 encoderDelay, 621 encoderPadding, 622 accessibilityChannel, 623 exoMediaCryptoType); 624 } 625 } 626 627 /** A value for various fields to indicate that the field's value is unknown or not applicable. */ 628 public static final int NO_VALUE = -1; 629 630 /** 631 * A value for {@link #subsampleOffsetUs} to indicate that subsample timestamps are relative to 632 * the timestamps of their parent samples. 633 */ 634 public static final long OFFSET_SAMPLE_RELATIVE = Long.MAX_VALUE; 635 636 /** An identifier for the format, or null if unknown or not applicable. */ 637 @Nullable public final String id; 638 /** The human readable label, or null if unknown or not applicable. */ 639 @Nullable public final String label; 640 /** The language as an IETF BCP 47 conformant tag, or null if unknown or not applicable. */ 641 @Nullable public final String language; 642 /** Track selection flags. */ 643 @C.SelectionFlags public final int selectionFlags; 644 /** Track role flags. */ 645 @C.RoleFlags public final int roleFlags; 646 /** 647 * The average bitrate in bits per second, or {@link #NO_VALUE} if unknown or not applicable. The 648 * way in which this field is populated depends on the type of media to which the format 649 * corresponds: 650 * 651 * <ul> 652 * <li>DASH representations: Always {@link Format#NO_VALUE}. 653 * <li>HLS variants: The {@code AVERAGE-BANDWIDTH} attribute defined on the corresponding {@code 654 * EXT-X-STREAM-INF} tag in the master playlist, or {@link Format#NO_VALUE} if not present. 655 * <li>SmoothStreaming track elements: The {@code Bitrate} attribute defined on the 656 * corresponding {@code TrackElement} in the manifest, or {@link Format#NO_VALUE} if not 657 * present. 658 * <li>Progressive container formats: Often {@link Format#NO_VALUE}, but may be populated with 659 * the average bitrate of the container if known. 660 * <li>Sample formats: Often {@link Format#NO_VALUE}, but may be populated with the average 661 * bitrate of the stream of samples with type {@link #sampleMimeType} if known. Note that if 662 * {@link #sampleMimeType} is a compressed format (e.g., {@link MimeTypes#AUDIO_AAC}), then 663 * this bitrate is for the stream of still compressed samples. 664 * </ul> 665 */ 666 public final int averageBitrate; 667 /** 668 * The peak bitrate in bits per second, or {@link #NO_VALUE} if unknown or not applicable. The way 669 * in which this field is populated depends on the type of media to which the format corresponds: 670 * 671 * <ul> 672 * <li>DASH representations: The {@code @bandwidth} attribute of the corresponding {@code 673 * Representation} element in the manifest. 674 * <li>HLS variants: The {@code BANDWIDTH} attribute defined on the corresponding {@code 675 * EXT-X-STREAM-INF} tag. 676 * <li>SmoothStreaming track elements: Always {@link Format#NO_VALUE}. 677 * <li>Progressive container formats: Often {@link Format#NO_VALUE}, but may be populated with 678 * the peak bitrate of the container if known. 679 * <li>Sample formats: Often {@link Format#NO_VALUE}, but may be populated with the peak bitrate 680 * of the stream of samples with type {@link #sampleMimeType} if known. Note that if {@link 681 * #sampleMimeType} is a compressed format (e.g., {@link MimeTypes#AUDIO_AAC}), then this 682 * bitrate is for the stream of still compressed samples. 683 * </ul> 684 */ 685 public final int peakBitrate; 686 /** 687 * The bitrate in bits per second. This is the peak bitrate if known, or else the average bitrate 688 * if known, or else {@link Format#NO_VALUE}. Equivalent to: {@code peakBitrate != NO_VALUE ? 689 * peakBitrate : averageBitrate}. 690 */ 691 public final int bitrate; 692 /** Codecs of the format as described in RFC 6381, or null if unknown or not applicable. */ 693 @Nullable public final String codecs; 694 /** Metadata, or null if unknown or not applicable. */ 695 @Nullable public final Metadata metadata; 696 697 // Container specific. 698 699 /** The mime type of the container, or null if unknown or not applicable. */ 700 @Nullable public final String containerMimeType; 701 702 // Sample specific. 703 704 /** The sample mime type, or null if unknown or not applicable. */ 705 @Nullable public final String sampleMimeType; 706 /** 707 * The maximum size of a buffer of data (typically one sample), or {@link #NO_VALUE} if unknown or 708 * not applicable. 709 */ 710 public final int maxInputSize; 711 /** 712 * Initialization data that must be provided to the decoder. Will not be null, but may be empty 713 * if initialization data is not required. 714 */ 715 public final List<byte[]> initializationData; 716 /** DRM initialization data if the stream is protected, or null otherwise. */ 717 @Nullable public final DrmInitData drmInitData; 718 719 /** 720 * For samples that contain subsamples, this is an offset that should be added to subsample 721 * timestamps. A value of {@link #OFFSET_SAMPLE_RELATIVE} indicates that subsample timestamps are 722 * relative to the timestamps of their parent samples. 723 */ 724 public final long subsampleOffsetUs; 725 726 // Video specific. 727 728 /** 729 * The width of the video in pixels, or {@link #NO_VALUE} if unknown or not applicable. 730 */ 731 public final int width; 732 /** 733 * The height of the video in pixels, or {@link #NO_VALUE} if unknown or not applicable. 734 */ 735 public final int height; 736 /** 737 * The frame rate in frames per second, or {@link #NO_VALUE} if unknown or not applicable. 738 */ 739 public final float frameRate; 740 /** 741 * The clockwise rotation that should be applied to the video for it to be rendered in the correct 742 * orientation, or 0 if unknown or not applicable. Only 0, 90, 180 and 270 are supported. 743 */ 744 public final int rotationDegrees; 745 /** The width to height ratio of pixels in the video, or 1.0 if unknown or not applicable. */ 746 public final float pixelWidthHeightRatio; 747 /** The projection data for 360/VR video, or null if not applicable. */ 748 @Nullable public final byte[] projectionData; 749 /** 750 * The stereo layout for 360/3D/VR video, or {@link #NO_VALUE} if not applicable. Valid stereo 751 * modes are {@link C#STEREO_MODE_MONO}, {@link C#STEREO_MODE_TOP_BOTTOM}, {@link 752 * C#STEREO_MODE_LEFT_RIGHT}, {@link C#STEREO_MODE_STEREO_MESH}. 753 */ 754 @C.StereoMode public final int stereoMode; 755 /** The color metadata associated with the video, or null if not applicable. */ 756 @Nullable public final ColorInfo colorInfo; 757 758 // Audio specific. 759 760 /** 761 * The number of audio channels, or {@link #NO_VALUE} if unknown or not applicable. 762 */ 763 public final int channelCount; 764 /** 765 * The audio sampling rate in Hz, or {@link #NO_VALUE} if unknown or not applicable. 766 */ 767 public final int sampleRate; 768 /** The {@link C.PcmEncoding} for PCM audio. Set to {@link #NO_VALUE} for other media types. */ 769 @C.PcmEncoding public final int pcmEncoding; 770 /** 771 * The number of frames to trim from the start of the decoded audio stream, or 0 if not 772 * applicable. 773 */ 774 public final int encoderDelay; 775 /** 776 * The number of frames to trim from the end of the decoded audio stream, or 0 if not applicable. 777 */ 778 public final int encoderPadding; 779 780 // Text specific. 781 782 /** The Accessibility channel, or {@link #NO_VALUE} if not known or applicable. */ 783 public final int accessibilityChannel; 784 785 // Provided by source. 786 787 /** 788 * The type of the {@link ExoMediaCrypto} provided by the media source, if the media source can 789 * acquire a DRM session for {@link #drmInitData}. Null if the media source cannot acquire a 790 * session for {@link #drmInitData}, or if not applicable. 791 */ 792 @Nullable public final Class<? extends ExoMediaCrypto> exoMediaCryptoType; 793 794 // Lazily initialized hashcode. 795 private int hashCode; 796 797 // Video. 798 799 /** @deprecated Use {@link Format.Builder}. */ 800 @Deprecated createVideoContainerFormat( @ullable String id, @Nullable String label, @Nullable String containerMimeType, @Nullable String sampleMimeType, @Nullable String codecs, @Nullable Metadata metadata, int bitrate, int width, int height, float frameRate, @Nullable List<byte[]> initializationData, @C.SelectionFlags int selectionFlags, @C.RoleFlags int roleFlags)801 public static Format createVideoContainerFormat( 802 @Nullable String id, 803 @Nullable String label, 804 @Nullable String containerMimeType, 805 @Nullable String sampleMimeType, 806 @Nullable String codecs, 807 @Nullable Metadata metadata, 808 int bitrate, 809 int width, 810 int height, 811 float frameRate, 812 @Nullable List<byte[]> initializationData, 813 @C.SelectionFlags int selectionFlags, 814 @C.RoleFlags int roleFlags) { 815 return new Builder() 816 .setId(id) 817 .setLabel(label) 818 .setSelectionFlags(selectionFlags) 819 .setRoleFlags(roleFlags) 820 .setAverageBitrate(bitrate) 821 .setPeakBitrate(bitrate) 822 .setCodecs(codecs) 823 .setMetadata(metadata) 824 .setContainerMimeType(containerMimeType) 825 .setSampleMimeType(sampleMimeType) 826 .setInitializationData(initializationData) 827 .setWidth(width) 828 .setHeight(height) 829 .setFrameRate(frameRate) 830 .build(); 831 } 832 833 /** @deprecated Use {@link Format.Builder}. */ 834 @Deprecated createVideoSampleFormat( @ullable String id, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, int maxInputSize, int width, int height, float frameRate, @Nullable List<byte[]> initializationData, @Nullable DrmInitData drmInitData)835 public static Format createVideoSampleFormat( 836 @Nullable String id, 837 @Nullable String sampleMimeType, 838 @Nullable String codecs, 839 int bitrate, 840 int maxInputSize, 841 int width, 842 int height, 843 float frameRate, 844 @Nullable List<byte[]> initializationData, 845 @Nullable DrmInitData drmInitData) { 846 return new Builder() 847 .setId(id) 848 .setAverageBitrate(bitrate) 849 .setPeakBitrate(bitrate) 850 .setCodecs(codecs) 851 .setSampleMimeType(sampleMimeType) 852 .setMaxInputSize(maxInputSize) 853 .setInitializationData(initializationData) 854 .setDrmInitData(drmInitData) 855 .setWidth(width) 856 .setHeight(height) 857 .setFrameRate(frameRate) 858 .build(); 859 } 860 861 /** @deprecated Use {@link Format.Builder}. */ 862 @Deprecated createVideoSampleFormat( @ullable String id, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, int maxInputSize, int width, int height, float frameRate, @Nullable List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio, @Nullable DrmInitData drmInitData)863 public static Format createVideoSampleFormat( 864 @Nullable String id, 865 @Nullable String sampleMimeType, 866 @Nullable String codecs, 867 int bitrate, 868 int maxInputSize, 869 int width, 870 int height, 871 float frameRate, 872 @Nullable List<byte[]> initializationData, 873 int rotationDegrees, 874 float pixelWidthHeightRatio, 875 @Nullable DrmInitData drmInitData) { 876 return new Builder() 877 .setId(id) 878 .setAverageBitrate(bitrate) 879 .setPeakBitrate(bitrate) 880 .setCodecs(codecs) 881 .setSampleMimeType(sampleMimeType) 882 .setMaxInputSize(maxInputSize) 883 .setInitializationData(initializationData) 884 .setDrmInitData(drmInitData) 885 .setWidth(width) 886 .setHeight(height) 887 .setFrameRate(frameRate) 888 .setRotationDegrees(rotationDegrees) 889 .setPixelWidthHeightRatio(pixelWidthHeightRatio) 890 .build(); 891 } 892 893 /** @deprecated Use {@link Format.Builder}. */ 894 @Deprecated createVideoSampleFormat( @ullable String id, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, int maxInputSize, int width, int height, float frameRate, @Nullable List<byte[]> initializationData, int rotationDegrees, float pixelWidthHeightRatio, @Nullable byte[] projectionData, @C.StereoMode int stereoMode, @Nullable ColorInfo colorInfo, @Nullable DrmInitData drmInitData)895 public static Format createVideoSampleFormat( 896 @Nullable String id, 897 @Nullable String sampleMimeType, 898 @Nullable String codecs, 899 int bitrate, 900 int maxInputSize, 901 int width, 902 int height, 903 float frameRate, 904 @Nullable List<byte[]> initializationData, 905 int rotationDegrees, 906 float pixelWidthHeightRatio, 907 @Nullable byte[] projectionData, 908 @C.StereoMode int stereoMode, 909 @Nullable ColorInfo colorInfo, 910 @Nullable DrmInitData drmInitData) { 911 return new Builder() 912 .setId(id) 913 .setAverageBitrate(bitrate) 914 .setPeakBitrate(bitrate) 915 .setCodecs(codecs) 916 .setSampleMimeType(sampleMimeType) 917 .setMaxInputSize(maxInputSize) 918 .setInitializationData(initializationData) 919 .setDrmInitData(drmInitData) 920 .setWidth(width) 921 .setHeight(height) 922 .setFrameRate(frameRate) 923 .setRotationDegrees(rotationDegrees) 924 .setPixelWidthHeightRatio(pixelWidthHeightRatio) 925 .setProjectionData(projectionData) 926 .setStereoMode(stereoMode) 927 .setColorInfo(colorInfo) 928 .build(); 929 } 930 931 // Audio. 932 933 /** @deprecated Use {@link Format.Builder}. */ 934 @Deprecated createAudioContainerFormat( @ullable String id, @Nullable String label, @Nullable String containerMimeType, @Nullable String sampleMimeType, @Nullable String codecs, @Nullable Metadata metadata, int bitrate, int channelCount, int sampleRate, @Nullable List<byte[]> initializationData, @C.SelectionFlags int selectionFlags, @C.RoleFlags int roleFlags, @Nullable String language)935 public static Format createAudioContainerFormat( 936 @Nullable String id, 937 @Nullable String label, 938 @Nullable String containerMimeType, 939 @Nullable String sampleMimeType, 940 @Nullable String codecs, 941 @Nullable Metadata metadata, 942 int bitrate, 943 int channelCount, 944 int sampleRate, 945 @Nullable List<byte[]> initializationData, 946 @C.SelectionFlags int selectionFlags, 947 @C.RoleFlags int roleFlags, 948 @Nullable String language) { 949 return new Builder() 950 .setId(id) 951 .setLabel(label) 952 .setLanguage(language) 953 .setSelectionFlags(selectionFlags) 954 .setRoleFlags(roleFlags) 955 .setAverageBitrate(bitrate) 956 .setPeakBitrate(bitrate) 957 .setCodecs(codecs) 958 .setMetadata(metadata) 959 .setContainerMimeType(containerMimeType) 960 .setSampleMimeType(sampleMimeType) 961 .setInitializationData(initializationData) 962 .setChannelCount(channelCount) 963 .setSampleRate(sampleRate) 964 .build(); 965 } 966 967 /** @deprecated Use {@link Format.Builder}. */ 968 @Deprecated createAudioSampleFormat( @ullable String id, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, int maxInputSize, int channelCount, int sampleRate, @Nullable List<byte[]> initializationData, @Nullable DrmInitData drmInitData, @C.SelectionFlags int selectionFlags, @Nullable String language)969 public static Format createAudioSampleFormat( 970 @Nullable String id, 971 @Nullable String sampleMimeType, 972 @Nullable String codecs, 973 int bitrate, 974 int maxInputSize, 975 int channelCount, 976 int sampleRate, 977 @Nullable List<byte[]> initializationData, 978 @Nullable DrmInitData drmInitData, 979 @C.SelectionFlags int selectionFlags, 980 @Nullable String language) { 981 return new Builder() 982 .setId(id) 983 .setLanguage(language) 984 .setSelectionFlags(selectionFlags) 985 .setAverageBitrate(bitrate) 986 .setPeakBitrate(bitrate) 987 .setCodecs(codecs) 988 .setSampleMimeType(sampleMimeType) 989 .setMaxInputSize(maxInputSize) 990 .setInitializationData(initializationData) 991 .setDrmInitData(drmInitData) 992 .setChannelCount(channelCount) 993 .setSampleRate(sampleRate) 994 .build(); 995 } 996 997 /** @deprecated Use {@link Format.Builder}. */ 998 @Deprecated createAudioSampleFormat( @ullable String id, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, int maxInputSize, int channelCount, int sampleRate, @C.PcmEncoding int pcmEncoding, @Nullable List<byte[]> initializationData, @Nullable DrmInitData drmInitData, @C.SelectionFlags int selectionFlags, @Nullable String language)999 public static Format createAudioSampleFormat( 1000 @Nullable String id, 1001 @Nullable String sampleMimeType, 1002 @Nullable String codecs, 1003 int bitrate, 1004 int maxInputSize, 1005 int channelCount, 1006 int sampleRate, 1007 @C.PcmEncoding int pcmEncoding, 1008 @Nullable List<byte[]> initializationData, 1009 @Nullable DrmInitData drmInitData, 1010 @C.SelectionFlags int selectionFlags, 1011 @Nullable String language) { 1012 return new Builder() 1013 .setId(id) 1014 .setLanguage(language) 1015 .setSelectionFlags(selectionFlags) 1016 .setAverageBitrate(bitrate) 1017 .setPeakBitrate(bitrate) 1018 .setCodecs(codecs) 1019 .setSampleMimeType(sampleMimeType) 1020 .setMaxInputSize(maxInputSize) 1021 .setInitializationData(initializationData) 1022 .setDrmInitData(drmInitData) 1023 .setChannelCount(channelCount) 1024 .setSampleRate(sampleRate) 1025 .setPcmEncoding(pcmEncoding) 1026 .build(); 1027 } 1028 1029 /** @deprecated Use {@link Format.Builder}. */ 1030 @Deprecated createAudioSampleFormat( @ullable String id, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, int maxInputSize, int channelCount, int sampleRate, @C.PcmEncoding int pcmEncoding, int encoderDelay, int encoderPadding, @Nullable List<byte[]> initializationData, @Nullable DrmInitData drmInitData, @C.SelectionFlags int selectionFlags, @Nullable String language, @Nullable Metadata metadata)1031 public static Format createAudioSampleFormat( 1032 @Nullable String id, 1033 @Nullable String sampleMimeType, 1034 @Nullable String codecs, 1035 int bitrate, 1036 int maxInputSize, 1037 int channelCount, 1038 int sampleRate, 1039 @C.PcmEncoding int pcmEncoding, 1040 int encoderDelay, 1041 int encoderPadding, 1042 @Nullable List<byte[]> initializationData, 1043 @Nullable DrmInitData drmInitData, 1044 @C.SelectionFlags int selectionFlags, 1045 @Nullable String language, 1046 @Nullable Metadata metadata) { 1047 return new Builder() 1048 .setId(id) 1049 .setLanguage(language) 1050 .setSelectionFlags(selectionFlags) 1051 .setAverageBitrate(bitrate) 1052 .setPeakBitrate(bitrate) 1053 .setCodecs(codecs) 1054 .setMetadata(metadata) 1055 .setSampleMimeType(sampleMimeType) 1056 .setMaxInputSize(maxInputSize) 1057 .setInitializationData(initializationData) 1058 .setDrmInitData(drmInitData) 1059 .setChannelCount(channelCount) 1060 .setSampleRate(sampleRate) 1061 .setPcmEncoding(pcmEncoding) 1062 .setEncoderDelay(encoderDelay) 1063 .setEncoderPadding(encoderPadding) 1064 .build(); 1065 } 1066 1067 // Text. 1068 1069 /** @deprecated Use {@link Format.Builder}. */ 1070 @Deprecated createTextContainerFormat( @ullable String id, @Nullable String label, @Nullable String containerMimeType, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, @C.SelectionFlags int selectionFlags, @C.RoleFlags int roleFlags, @Nullable String language)1071 public static Format createTextContainerFormat( 1072 @Nullable String id, 1073 @Nullable String label, 1074 @Nullable String containerMimeType, 1075 @Nullable String sampleMimeType, 1076 @Nullable String codecs, 1077 int bitrate, 1078 @C.SelectionFlags int selectionFlags, 1079 @C.RoleFlags int roleFlags, 1080 @Nullable String language) { 1081 return new Builder() 1082 .setId(id) 1083 .setLabel(label) 1084 .setLanguage(language) 1085 .setSelectionFlags(selectionFlags) 1086 .setRoleFlags(roleFlags) 1087 .setAverageBitrate(bitrate) 1088 .setPeakBitrate(bitrate) 1089 .setCodecs(codecs) 1090 .setContainerMimeType(containerMimeType) 1091 .setSampleMimeType(sampleMimeType) 1092 .build(); 1093 } 1094 1095 /** @deprecated Use {@link Format.Builder}. */ 1096 @Deprecated createTextContainerFormat( @ullable String id, @Nullable String label, @Nullable String containerMimeType, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, @C.SelectionFlags int selectionFlags, @C.RoleFlags int roleFlags, @Nullable String language, int accessibilityChannel)1097 public static Format createTextContainerFormat( 1098 @Nullable String id, 1099 @Nullable String label, 1100 @Nullable String containerMimeType, 1101 @Nullable String sampleMimeType, 1102 @Nullable String codecs, 1103 int bitrate, 1104 @C.SelectionFlags int selectionFlags, 1105 @C.RoleFlags int roleFlags, 1106 @Nullable String language, 1107 int accessibilityChannel) { 1108 return new Builder() 1109 .setId(id) 1110 .setLabel(label) 1111 .setLanguage(language) 1112 .setSelectionFlags(selectionFlags) 1113 .setRoleFlags(roleFlags) 1114 .setAverageBitrate(bitrate) 1115 .setPeakBitrate(bitrate) 1116 .setCodecs(codecs) 1117 .setContainerMimeType(containerMimeType) 1118 .setSampleMimeType(sampleMimeType) 1119 .setAccessibilityChannel(accessibilityChannel) 1120 .build(); 1121 } 1122 1123 /** @deprecated Use {@link Format.Builder}. */ 1124 @Deprecated createTextSampleFormat( @ullable String id, @Nullable String sampleMimeType, @C.SelectionFlags int selectionFlags, @Nullable String language)1125 public static Format createTextSampleFormat( 1126 @Nullable String id, 1127 @Nullable String sampleMimeType, 1128 @C.SelectionFlags int selectionFlags, 1129 @Nullable String language) { 1130 return new Builder() 1131 .setId(id) 1132 .setLanguage(language) 1133 .setSelectionFlags(selectionFlags) 1134 .setSampleMimeType(sampleMimeType) 1135 .build(); 1136 } 1137 1138 /** @deprecated Use {@link Format.Builder}. */ 1139 @Deprecated createTextSampleFormat( @ullable String id, @Nullable String sampleMimeType, @C.SelectionFlags int selectionFlags, @Nullable String language, int accessibilityChannel, long subsampleOffsetUs, @Nullable List<byte[]> initializationData)1140 public static Format createTextSampleFormat( 1141 @Nullable String id, 1142 @Nullable String sampleMimeType, 1143 @C.SelectionFlags int selectionFlags, 1144 @Nullable String language, 1145 int accessibilityChannel, 1146 long subsampleOffsetUs, 1147 @Nullable List<byte[]> initializationData) { 1148 return new Builder() 1149 .setId(id) 1150 .setLanguage(language) 1151 .setSelectionFlags(selectionFlags) 1152 .setSampleMimeType(sampleMimeType) 1153 .setInitializationData(initializationData) 1154 .setSubsampleOffsetUs(subsampleOffsetUs) 1155 .setAccessibilityChannel(accessibilityChannel) 1156 .build(); 1157 } 1158 1159 // Image. 1160 1161 /** @deprecated Use {@link Format.Builder}. */ 1162 @Deprecated createImageSampleFormat( @ullable String id, @Nullable String sampleMimeType, @C.SelectionFlags int selectionFlags, @Nullable List<byte[]> initializationData, @Nullable String language)1163 public static Format createImageSampleFormat( 1164 @Nullable String id, 1165 @Nullable String sampleMimeType, 1166 @C.SelectionFlags int selectionFlags, 1167 @Nullable List<byte[]> initializationData, 1168 @Nullable String language) { 1169 return new Builder() 1170 .setId(id) 1171 .setLanguage(language) 1172 .setSelectionFlags(selectionFlags) 1173 .setSampleMimeType(sampleMimeType) 1174 .setInitializationData(initializationData) 1175 .build(); 1176 } 1177 1178 // Generic. 1179 1180 /** @deprecated Use {@link Format.Builder}. */ 1181 @Deprecated createContainerFormat( @ullable String id, @Nullable String label, @Nullable String containerMimeType, @Nullable String sampleMimeType, @Nullable String codecs, int bitrate, @C.SelectionFlags int selectionFlags, @C.RoleFlags int roleFlags, @Nullable String language)1182 public static Format createContainerFormat( 1183 @Nullable String id, 1184 @Nullable String label, 1185 @Nullable String containerMimeType, 1186 @Nullable String sampleMimeType, 1187 @Nullable String codecs, 1188 int bitrate, 1189 @C.SelectionFlags int selectionFlags, 1190 @C.RoleFlags int roleFlags, 1191 @Nullable String language) { 1192 return new Builder() 1193 .setId(id) 1194 .setLabel(label) 1195 .setLanguage(language) 1196 .setSelectionFlags(selectionFlags) 1197 .setRoleFlags(roleFlags) 1198 .setAverageBitrate(bitrate) 1199 .setPeakBitrate(bitrate) 1200 .setCodecs(codecs) 1201 .setContainerMimeType(containerMimeType) 1202 .setSampleMimeType(sampleMimeType) 1203 .build(); 1204 } 1205 1206 /** @deprecated Use {@link Format.Builder}. */ 1207 @Deprecated createSampleFormat(@ullable String id, @Nullable String sampleMimeType)1208 public static Format createSampleFormat(@Nullable String id, @Nullable String sampleMimeType) { 1209 return new Builder().setId(id).setSampleMimeType(sampleMimeType).build(); 1210 } 1211 Format( @ullable String id, @Nullable String label, @Nullable String language, @C.SelectionFlags int selectionFlags, @C.RoleFlags int roleFlags, int averageBitrate, int peakBitrate, @Nullable String codecs, @Nullable Metadata metadata, @Nullable String containerMimeType, @Nullable String sampleMimeType, int maxInputSize, @Nullable List<byte[]> initializationData, @Nullable DrmInitData drmInitData, long subsampleOffsetUs, int width, int height, float frameRate, int rotationDegrees, float pixelWidthHeightRatio, @Nullable byte[] projectionData, @C.StereoMode int stereoMode, @Nullable ColorInfo colorInfo, int channelCount, int sampleRate, @C.PcmEncoding int pcmEncoding, int encoderDelay, int encoderPadding, int accessibilityChannel, @Nullable Class<? extends ExoMediaCrypto> exoMediaCryptoType)1212 /* package */ Format( 1213 @Nullable String id, 1214 @Nullable String label, 1215 @Nullable String language, 1216 @C.SelectionFlags int selectionFlags, 1217 @C.RoleFlags int roleFlags, 1218 int averageBitrate, 1219 int peakBitrate, 1220 @Nullable String codecs, 1221 @Nullable Metadata metadata, 1222 // Container specific. 1223 @Nullable String containerMimeType, 1224 // Sample specific. 1225 @Nullable String sampleMimeType, 1226 int maxInputSize, 1227 @Nullable List<byte[]> initializationData, 1228 @Nullable DrmInitData drmInitData, 1229 long subsampleOffsetUs, 1230 // Video specific. 1231 int width, 1232 int height, 1233 float frameRate, 1234 int rotationDegrees, 1235 float pixelWidthHeightRatio, 1236 @Nullable byte[] projectionData, 1237 @C.StereoMode int stereoMode, 1238 @Nullable ColorInfo colorInfo, 1239 // Audio specific. 1240 int channelCount, 1241 int sampleRate, 1242 @C.PcmEncoding int pcmEncoding, 1243 int encoderDelay, 1244 int encoderPadding, 1245 // Text specific. 1246 int accessibilityChannel, 1247 // Provided by source. 1248 @Nullable Class<? extends ExoMediaCrypto> exoMediaCryptoType) { 1249 this.id = id; 1250 this.label = label; 1251 this.language = Util.normalizeLanguageCode(language); 1252 this.selectionFlags = selectionFlags; 1253 this.roleFlags = roleFlags; 1254 this.averageBitrate = averageBitrate; 1255 this.peakBitrate = peakBitrate; 1256 this.bitrate = peakBitrate != NO_VALUE ? peakBitrate : averageBitrate; 1257 this.codecs = codecs; 1258 this.metadata = metadata; 1259 // Container specific. 1260 this.containerMimeType = containerMimeType; 1261 // Sample specific. 1262 this.sampleMimeType = sampleMimeType; 1263 this.maxInputSize = maxInputSize; 1264 this.initializationData = 1265 initializationData == null ? Collections.emptyList() : initializationData; 1266 this.drmInitData = drmInitData; 1267 this.subsampleOffsetUs = subsampleOffsetUs; 1268 // Video specific. 1269 this.width = width; 1270 this.height = height; 1271 this.frameRate = frameRate; 1272 this.rotationDegrees = rotationDegrees == NO_VALUE ? 0 : rotationDegrees; 1273 this.pixelWidthHeightRatio = pixelWidthHeightRatio == NO_VALUE ? 1 : pixelWidthHeightRatio; 1274 this.projectionData = projectionData; 1275 this.stereoMode = stereoMode; 1276 this.colorInfo = colorInfo; 1277 // Audio specific. 1278 this.channelCount = channelCount; 1279 this.sampleRate = sampleRate; 1280 this.pcmEncoding = pcmEncoding; 1281 this.encoderDelay = encoderDelay == NO_VALUE ? 0 : encoderDelay; 1282 this.encoderPadding = encoderPadding == NO_VALUE ? 0 : encoderPadding; 1283 // Text specific. 1284 this.accessibilityChannel = accessibilityChannel; 1285 // Provided by source. 1286 this.exoMediaCryptoType = exoMediaCryptoType; 1287 } 1288 1289 @SuppressWarnings("ResourceType") Format(Parcel in)1290 /* package */ Format(Parcel in) { 1291 id = in.readString(); 1292 label = in.readString(); 1293 language = in.readString(); 1294 selectionFlags = in.readInt(); 1295 roleFlags = in.readInt(); 1296 averageBitrate = in.readInt(); 1297 peakBitrate = in.readInt(); 1298 bitrate = peakBitrate != NO_VALUE ? peakBitrate : averageBitrate; 1299 codecs = in.readString(); 1300 metadata = in.readParcelable(Metadata.class.getClassLoader()); 1301 // Container specific. 1302 containerMimeType = in.readString(); 1303 // Sample specific. 1304 sampleMimeType = in.readString(); 1305 maxInputSize = in.readInt(); 1306 int initializationDataSize = in.readInt(); 1307 initializationData = new ArrayList<>(initializationDataSize); 1308 for (int i = 0; i < initializationDataSize; i++) { 1309 initializationData.add(in.createByteArray()); 1310 } 1311 drmInitData = in.readParcelable(DrmInitData.class.getClassLoader()); 1312 subsampleOffsetUs = in.readLong(); 1313 // Video specific. 1314 width = in.readInt(); 1315 height = in.readInt(); 1316 frameRate = in.readFloat(); 1317 rotationDegrees = in.readInt(); 1318 pixelWidthHeightRatio = in.readFloat(); 1319 boolean hasProjectionData = Util.readBoolean(in); 1320 projectionData = hasProjectionData ? in.createByteArray() : null; 1321 stereoMode = in.readInt(); 1322 colorInfo = in.readParcelable(ColorInfo.class.getClassLoader()); 1323 // Audio specific. 1324 channelCount = in.readInt(); 1325 sampleRate = in.readInt(); 1326 pcmEncoding = in.readInt(); 1327 encoderDelay = in.readInt(); 1328 encoderPadding = in.readInt(); 1329 // Text specific. 1330 accessibilityChannel = in.readInt(); 1331 // Provided by source. 1332 exoMediaCryptoType = null; 1333 } 1334 1335 /** Returns a {@link Format.Builder} initialized with the values of this instance. */ buildUpon()1336 public Builder buildUpon() { 1337 return new Builder(this); 1338 } 1339 1340 /** @deprecated Use {@link #buildUpon()} and {@link Builder#setMaxInputSize(int)}. */ 1341 @Deprecated copyWithMaxInputSize(int maxInputSize)1342 public Format copyWithMaxInputSize(int maxInputSize) { 1343 return buildUpon().setMaxInputSize(maxInputSize).build(); 1344 } 1345 1346 /** @deprecated Use {@link #buildUpon()} and {@link Builder#setSubsampleOffsetUs(long)}. */ 1347 @Deprecated copyWithSubsampleOffsetUs(long subsampleOffsetUs)1348 public Format copyWithSubsampleOffsetUs(long subsampleOffsetUs) { 1349 return buildUpon().setSubsampleOffsetUs(subsampleOffsetUs).build(); 1350 } 1351 1352 /** @deprecated Use {@link #buildUpon()} and {@link Builder#setLabel(String)} . */ 1353 @Deprecated copyWithLabel(@ullable String label)1354 public Format copyWithLabel(@Nullable String label) { 1355 return buildUpon().setLabel(label).build(); 1356 } 1357 1358 /** @deprecated Use {@link #withManifestFormatInfo(Format)}. */ 1359 @Deprecated copyWithManifestFormatInfo(Format manifestFormat)1360 public Format copyWithManifestFormatInfo(Format manifestFormat) { 1361 return withManifestFormatInfo(manifestFormat); 1362 } 1363 1364 @SuppressWarnings("ReferenceEquality") withManifestFormatInfo(Format manifestFormat)1365 public Format withManifestFormatInfo(Format manifestFormat) { 1366 if (this == manifestFormat) { 1367 // No need to copy from ourselves. 1368 return this; 1369 } 1370 1371 int trackType = MimeTypes.getTrackType(sampleMimeType); 1372 1373 // Use manifest value only. 1374 @Nullable String id = manifestFormat.id; 1375 1376 // Prefer manifest values, but fill in from sample format if missing. 1377 @Nullable String label = manifestFormat.label != null ? manifestFormat.label : this.label; 1378 @Nullable String language = this.language; 1379 if ((trackType == C.TRACK_TYPE_TEXT || trackType == C.TRACK_TYPE_AUDIO) 1380 && manifestFormat.language != null) { 1381 language = manifestFormat.language; 1382 } 1383 1384 // Prefer sample format values, but fill in from manifest if missing. 1385 int averageBitrate = 1386 this.averageBitrate == NO_VALUE ? manifestFormat.averageBitrate : this.averageBitrate; 1387 int peakBitrate = this.peakBitrate == NO_VALUE ? manifestFormat.peakBitrate : this.peakBitrate; 1388 @Nullable String codecs = this.codecs; 1389 if (codecs == null) { 1390 // The manifest format may be muxed, so filter only codecs of this format's type. If we still 1391 // have more than one codec then we're unable to uniquely identify which codec to fill in. 1392 @Nullable String codecsOfType = Util.getCodecsOfType(manifestFormat.codecs, trackType); 1393 if (Util.splitCodecs(codecsOfType).length == 1) { 1394 codecs = codecsOfType; 1395 } 1396 } 1397 1398 @Nullable 1399 Metadata metadata = 1400 this.metadata == null 1401 ? manifestFormat.metadata 1402 : this.metadata.copyWithAppendedEntriesFrom(manifestFormat.metadata); 1403 1404 float frameRate = this.frameRate; 1405 if (frameRate == NO_VALUE && trackType == C.TRACK_TYPE_VIDEO) { 1406 frameRate = manifestFormat.frameRate; 1407 } 1408 1409 // Merge manifest and sample format values. 1410 @C.SelectionFlags int selectionFlags = this.selectionFlags | manifestFormat.selectionFlags; 1411 @C.RoleFlags int roleFlags = this.roleFlags | manifestFormat.roleFlags; 1412 @Nullable 1413 DrmInitData drmInitData = 1414 DrmInitData.createSessionCreationData(manifestFormat.drmInitData, this.drmInitData); 1415 1416 return buildUpon() 1417 .setId(id) 1418 .setLabel(label) 1419 .setLanguage(language) 1420 .setSelectionFlags(selectionFlags) 1421 .setRoleFlags(roleFlags) 1422 .setAverageBitrate(averageBitrate) 1423 .setPeakBitrate(peakBitrate) 1424 .setCodecs(codecs) 1425 .setMetadata(metadata) 1426 .setDrmInitData(drmInitData) 1427 .setFrameRate(frameRate) 1428 .build(); 1429 } 1430 1431 /** 1432 * @deprecated Use {@link #buildUpon()}, {@link Builder#setEncoderDelay(int)} and {@link 1433 * Builder#setEncoderPadding(int)}. 1434 */ 1435 @Deprecated copyWithGaplessInfo(int encoderDelay, int encoderPadding)1436 public Format copyWithGaplessInfo(int encoderDelay, int encoderPadding) { 1437 return buildUpon().setEncoderDelay(encoderDelay).setEncoderPadding(encoderPadding).build(); 1438 } 1439 1440 /** @deprecated Use {@link #buildUpon()} and {@link Builder#setFrameRate(float)}. */ 1441 @Deprecated copyWithFrameRate(float frameRate)1442 public Format copyWithFrameRate(float frameRate) { 1443 return buildUpon().setFrameRate(frameRate).build(); 1444 } 1445 1446 /** @deprecated Use {@link #buildUpon()} and {@link Builder#setDrmInitData(DrmInitData)}. */ 1447 @Deprecated copyWithDrmInitData(@ullable DrmInitData drmInitData)1448 public Format copyWithDrmInitData(@Nullable DrmInitData drmInitData) { 1449 return buildUpon().setDrmInitData(drmInitData).build(); 1450 } 1451 1452 /** @deprecated Use {@link #buildUpon()} and {@link Builder#setMetadata(Metadata)}. */ 1453 @Deprecated copyWithMetadata(@ullable Metadata metadata)1454 public Format copyWithMetadata(@Nullable Metadata metadata) { 1455 return buildUpon().setMetadata(metadata).build(); 1456 } 1457 1458 /** 1459 * @deprecated Use {@link #buildUpon()} and {@link Builder#setAverageBitrate(int)} and {@link 1460 * Builder#setPeakBitrate(int)}. 1461 */ 1462 @Deprecated copyWithBitrate(int bitrate)1463 public Format copyWithBitrate(int bitrate) { 1464 return buildUpon().setAverageBitrate(bitrate).setPeakBitrate(bitrate).build(); 1465 } 1466 1467 /** 1468 * @deprecated Use {@link #buildUpon()}, {@link Builder#setWidth(int)} and {@link 1469 * Builder#setHeight(int)}. 1470 */ 1471 @Deprecated copyWithVideoSize(int width, int height)1472 public Format copyWithVideoSize(int width, int height) { 1473 return buildUpon().setWidth(width).setHeight(height).build(); 1474 } 1475 1476 /** Returns a copy of this format with the specified {@link #exoMediaCryptoType}. */ copyWithExoMediaCryptoType( @ullable Class<? extends ExoMediaCrypto> exoMediaCryptoType)1477 public Format copyWithExoMediaCryptoType( 1478 @Nullable Class<? extends ExoMediaCrypto> exoMediaCryptoType) { 1479 return buildUpon().setExoMediaCryptoType(exoMediaCryptoType).build(); 1480 } 1481 1482 /** 1483 * Returns the number of pixels if this is a video format whose {@link #width} and {@link #height} 1484 * are known, or {@link #NO_VALUE} otherwise 1485 */ getPixelCount()1486 public int getPixelCount() { 1487 return width == NO_VALUE || height == NO_VALUE ? NO_VALUE : (width * height); 1488 } 1489 1490 @Override toString()1491 public String toString() { 1492 return "Format(" 1493 + id 1494 + ", " 1495 + label 1496 + ", " 1497 + containerMimeType 1498 + ", " 1499 + sampleMimeType 1500 + ", " 1501 + codecs 1502 + ", " 1503 + bitrate 1504 + ", " 1505 + language 1506 + ", [" 1507 + width 1508 + ", " 1509 + height 1510 + ", " 1511 + frameRate 1512 + "]" 1513 + ", [" 1514 + channelCount 1515 + ", " 1516 + sampleRate 1517 + "])"; 1518 } 1519 1520 @Override hashCode()1521 public int hashCode() { 1522 if (hashCode == 0) { 1523 // Some fields for which hashing is expensive are deliberately omitted. 1524 int result = 17; 1525 result = 31 * result + (id == null ? 0 : id.hashCode()); 1526 result = 31 * result + (label != null ? label.hashCode() : 0); 1527 result = 31 * result + (language == null ? 0 : language.hashCode()); 1528 result = 31 * result + selectionFlags; 1529 result = 31 * result + roleFlags; 1530 result = 31 * result + averageBitrate; 1531 result = 31 * result + peakBitrate; 1532 result = 31 * result + (codecs == null ? 0 : codecs.hashCode()); 1533 result = 31 * result + (metadata == null ? 0 : metadata.hashCode()); 1534 // Container specific. 1535 result = 31 * result + (containerMimeType == null ? 0 : containerMimeType.hashCode()); 1536 // Sample specific. 1537 result = 31 * result + (sampleMimeType == null ? 0 : sampleMimeType.hashCode()); 1538 result = 31 * result + maxInputSize; 1539 // [Omitted] initializationData. 1540 // [Omitted] drmInitData. 1541 result = 31 * result + (int) subsampleOffsetUs; 1542 // Video specific. 1543 result = 31 * result + width; 1544 result = 31 * result + height; 1545 result = 31 * result + Float.floatToIntBits(frameRate); 1546 result = 31 * result + rotationDegrees; 1547 result = 31 * result + Float.floatToIntBits(pixelWidthHeightRatio); 1548 // [Omitted] projectionData. 1549 result = 31 * result + stereoMode; 1550 // [Omitted] colorInfo. 1551 // Audio specific. 1552 result = 31 * result + channelCount; 1553 result = 31 * result + sampleRate; 1554 result = 31 * result + pcmEncoding; 1555 result = 31 * result + encoderDelay; 1556 result = 31 * result + encoderPadding; 1557 // Text specific. 1558 result = 31 * result + accessibilityChannel; 1559 // Provided by source. 1560 result = 31 * result + (exoMediaCryptoType == null ? 0 : exoMediaCryptoType.hashCode()); 1561 hashCode = result; 1562 } 1563 return hashCode; 1564 } 1565 1566 @Override equals(@ullable Object obj)1567 public boolean equals(@Nullable Object obj) { 1568 if (this == obj) { 1569 return true; 1570 } 1571 if (obj == null || getClass() != obj.getClass()) { 1572 return false; 1573 } 1574 Format other = (Format) obj; 1575 if (hashCode != 0 && other.hashCode != 0 && hashCode != other.hashCode) { 1576 return false; 1577 } 1578 // Field equality checks ordered by type, with the cheapest checks first. 1579 return selectionFlags == other.selectionFlags 1580 && roleFlags == other.roleFlags 1581 && averageBitrate == other.averageBitrate 1582 && peakBitrate == other.peakBitrate 1583 && maxInputSize == other.maxInputSize 1584 && subsampleOffsetUs == other.subsampleOffsetUs 1585 && width == other.width 1586 && height == other.height 1587 && rotationDegrees == other.rotationDegrees 1588 && stereoMode == other.stereoMode 1589 && channelCount == other.channelCount 1590 && sampleRate == other.sampleRate 1591 && pcmEncoding == other.pcmEncoding 1592 && encoderDelay == other.encoderDelay 1593 && encoderPadding == other.encoderPadding 1594 && accessibilityChannel == other.accessibilityChannel 1595 && Float.compare(frameRate, other.frameRate) == 0 1596 && Float.compare(pixelWidthHeightRatio, other.pixelWidthHeightRatio) == 0 1597 && Util.areEqual(exoMediaCryptoType, other.exoMediaCryptoType) 1598 && Util.areEqual(id, other.id) 1599 && Util.areEqual(label, other.label) 1600 && Util.areEqual(codecs, other.codecs) 1601 && Util.areEqual(containerMimeType, other.containerMimeType) 1602 && Util.areEqual(sampleMimeType, other.sampleMimeType) 1603 && Util.areEqual(language, other.language) 1604 && Arrays.equals(projectionData, other.projectionData) 1605 && Util.areEqual(metadata, other.metadata) 1606 && Util.areEqual(colorInfo, other.colorInfo) 1607 && Util.areEqual(drmInitData, other.drmInitData) 1608 && initializationDataEquals(other); 1609 } 1610 1611 /** 1612 * Returns whether the {@link #initializationData}s belonging to this format and {@code other} are 1613 * equal. 1614 * 1615 * @param other The other format whose {@link #initializationData} is being compared. 1616 * @return Whether the {@link #initializationData}s belonging to this format and {@code other} are 1617 * equal. 1618 */ initializationDataEquals(Format other)1619 public boolean initializationDataEquals(Format other) { 1620 if (initializationData.size() != other.initializationData.size()) { 1621 return false; 1622 } 1623 for (int i = 0; i < initializationData.size(); i++) { 1624 if (!Arrays.equals(initializationData.get(i), other.initializationData.get(i))) { 1625 return false; 1626 } 1627 } 1628 return true; 1629 } 1630 1631 // Utility methods 1632 1633 /** Returns a prettier {@link String} than {@link #toString()}, intended for logging. */ toLogString(@ullable Format format)1634 public static String toLogString(@Nullable Format format) { 1635 if (format == null) { 1636 return "null"; 1637 } 1638 StringBuilder builder = new StringBuilder(); 1639 builder.append("id=").append(format.id).append(", mimeType=").append(format.sampleMimeType); 1640 if (format.bitrate != NO_VALUE) { 1641 builder.append(", bitrate=").append(format.bitrate); 1642 } 1643 if (format.codecs != null) { 1644 builder.append(", codecs=").append(format.codecs); 1645 } 1646 if (format.width != NO_VALUE && format.height != NO_VALUE) { 1647 builder.append(", res=").append(format.width).append("x").append(format.height); 1648 } 1649 if (format.frameRate != NO_VALUE) { 1650 builder.append(", fps=").append(format.frameRate); 1651 } 1652 if (format.channelCount != NO_VALUE) { 1653 builder.append(", channels=").append(format.channelCount); 1654 } 1655 if (format.sampleRate != NO_VALUE) { 1656 builder.append(", sample_rate=").append(format.sampleRate); 1657 } 1658 if (format.language != null) { 1659 builder.append(", language=").append(format.language); 1660 } 1661 if (format.label != null) { 1662 builder.append(", label=").append(format.label); 1663 } 1664 return builder.toString(); 1665 } 1666 1667 // Parcelable implementation. 1668 1669 @Override describeContents()1670 public int describeContents() { 1671 return 0; 1672 } 1673 1674 @Override writeToParcel(Parcel dest, int flags)1675 public void writeToParcel(Parcel dest, int flags) { 1676 dest.writeString(id); 1677 dest.writeString(label); 1678 dest.writeString(language); 1679 dest.writeInt(selectionFlags); 1680 dest.writeInt(roleFlags); 1681 dest.writeInt(averageBitrate); 1682 dest.writeInt(peakBitrate); 1683 dest.writeString(codecs); 1684 dest.writeParcelable(metadata, 0); 1685 // Container specific. 1686 dest.writeString(containerMimeType); 1687 // Sample specific. 1688 dest.writeString(sampleMimeType); 1689 dest.writeInt(maxInputSize); 1690 int initializationDataSize = initializationData.size(); 1691 dest.writeInt(initializationDataSize); 1692 for (int i = 0; i < initializationDataSize; i++) { 1693 dest.writeByteArray(initializationData.get(i)); 1694 } 1695 dest.writeParcelable(drmInitData, 0); 1696 dest.writeLong(subsampleOffsetUs); 1697 // Video specific. 1698 dest.writeInt(width); 1699 dest.writeInt(height); 1700 dest.writeFloat(frameRate); 1701 dest.writeInt(rotationDegrees); 1702 dest.writeFloat(pixelWidthHeightRatio); 1703 Util.writeBoolean(dest, projectionData != null); 1704 if (projectionData != null) { 1705 dest.writeByteArray(projectionData); 1706 } 1707 dest.writeInt(stereoMode); 1708 dest.writeParcelable(colorInfo, flags); 1709 // Audio specific. 1710 dest.writeInt(channelCount); 1711 dest.writeInt(sampleRate); 1712 dest.writeInt(pcmEncoding); 1713 dest.writeInt(encoderDelay); 1714 dest.writeInt(encoderPadding); 1715 // Text specific. 1716 dest.writeInt(accessibilityChannel); 1717 } 1718 1719 public static final Creator<Format> CREATOR = new Creator<Format>() { 1720 1721 @Override 1722 public Format createFromParcel(Parcel in) { 1723 return new Format(in); 1724 } 1725 1726 @Override 1727 public Format[] newArray(int size) { 1728 return new Format[size]; 1729 } 1730 1731 }; 1732 } 1733