mirror of
https://github.com/androidx/media.git
synced 2025-05-11 09:39:52 +08:00
Merge branch 'dev-v2' of https://github.com/google/ExoPlayer into dev-v2
This commit is contained in:
commit
8ab76ac9fb
@ -2,38 +2,34 @@
|
|||||||
|
|
||||||
### dev-v2 (not yet released)
|
### dev-v2 (not yet released)
|
||||||
|
|
||||||
|
### 2.16.0 (2021-11-04)
|
||||||
|
|
||||||
* Core Library:
|
* Core Library:
|
||||||
|
* Deprecate `SimpleExoPlayer`. All functionality has been moved to
|
||||||
|
`ExoPlayer` instead. `ExoPlayer.Builder` can be used instead of
|
||||||
|
`SimpleExoPlayer.Builder`.
|
||||||
|
* Add track selection methods to the `Player` interface, for example,
|
||||||
|
`Player.getCurrentTracksInfo` and `Player.setTrackSelectionParameters`.
|
||||||
|
These methods can be used instead of directly accessing the track
|
||||||
|
selector.
|
||||||
* Enable MediaCodec asynchronous queueing by default on devices with API
|
* Enable MediaCodec asynchronous queueing by default on devices with API
|
||||||
level >= 31. Add methods in `DefaultMediaCodecRendererFactory` and
|
level >= 31. Add methods in `DefaultMediaCodecRendererFactory` and
|
||||||
`DefaultRenderersFactory` to force enable or force disable asynchronous
|
`DefaultRenderersFactory` to force enable or force disable asynchronous
|
||||||
queueing ([6348](https://github.com/google/ExoPlayer/issues/6348)).
|
queueing ([6348](https://github.com/google/ExoPlayer/issues/6348)).
|
||||||
* Add 12 public method headers to `ExoPlayer` that exist in
|
* Remove final dependency on `jcenter()`.
|
||||||
`SimpleExoPlayer`, such that all public methods in `SimpleExoPlayer` are
|
* Fix `mediaMetadata` being reset when media is repeated
|
||||||
overrides.
|
([#9458](https://github.com/google/ExoPlayer/issues/9458)).
|
||||||
|
* Adjust `ExoPlayer` `MediaMetadata` update priority, such that values
|
||||||
|
input through the `MediaItem.MediaMetadata` are used above media derived
|
||||||
|
values.
|
||||||
* Move `com.google.android.exoplayer2.device.DeviceInfo` to
|
* Move `com.google.android.exoplayer2.device.DeviceInfo` to
|
||||||
`com.google.android.exoplayer2.DeviceInfo`.
|
`com.google.android.exoplayer2.DeviceInfo`.
|
||||||
* Move `com.google.android.exoplayer2.drm.DecryptionException` to
|
* Move `com.google.android.exoplayer2.drm.DecryptionException` to
|
||||||
`com.google.android.exoplayer2.decoder.CryptoException`.
|
`com.google.android.exoplayer2.decoder.CryptoException`.
|
||||||
* Move `com.google.android.exoplayer2.upstream.cache.CachedRegionTracker`
|
* Move `com.google.android.exoplayer2.upstream.cache.CachedRegionTracker`
|
||||||
to `com.google.android.exoplayer2.upstream.CachedRegionTracker`.
|
to `com.google.android.exoplayer2.upstream.CachedRegionTracker`.
|
||||||
* Remove `ExoPlayerLibraryInfo.GL_ASSERTIONS_ENABLED`. Use
|
|
||||||
`GlUtil.glAssertionsEnabled` instead.
|
|
||||||
* Move `Player.addListener(EventListener)` and
|
* Move `Player.addListener(EventListener)` and
|
||||||
`Player.removeListener(EventListener)` out of `Player` into subclasses.
|
`Player.removeListener(EventListener)` out of `Player` into subclasses.
|
||||||
* Fix `mediaMetadata` being reset when media is repeated
|
|
||||||
([#9458](https://github.com/google/ExoPlayer/issues/9458)).
|
|
||||||
* Remove final dependency on `jcenter()`.
|
|
||||||
* Adjust `ExoPlayer` `MediaMetadata` update priority, such that values
|
|
||||||
input through the `MediaItem.MediaMetadata` are used above media derived
|
|
||||||
values.
|
|
||||||
* Video:
|
|
||||||
* Fix bug in `MediaCodecVideoRenderer` that resulted in re-using a
|
|
||||||
released `Surface` when playing without an app-provided `Surface`
|
|
||||||
([#9476](https://github.com/google/ExoPlayer/issues/9476)).
|
|
||||||
* DRM:
|
|
||||||
* Log an error (instead of throwing `IllegalStateException`) when calling
|
|
||||||
`DefaultDrmSession#release()` on a fully released session
|
|
||||||
([#9392](https://github.com/google/ExoPlayer/issues/9392)).
|
|
||||||
* Android 12 compatibility:
|
* Android 12 compatibility:
|
||||||
* Keep `DownloadService` started and in the foreground whilst waiting for
|
* Keep `DownloadService` started and in the foreground whilst waiting for
|
||||||
requirements to be met on Android 12. This is necessary due to new
|
requirements to be met on Android 12. This is necessary due to new
|
||||||
@ -49,6 +45,14 @@
|
|||||||
are not compatible with apps targeting Android 12, and will crash with
|
are not compatible with apps targeting Android 12, and will crash with
|
||||||
an `IllegalArgumentException` when creating `PendingIntent`s
|
an `IllegalArgumentException` when creating `PendingIntent`s
|
||||||
([#9181](https://github.com/google/ExoPlayer/issues/9181)).
|
([#9181](https://github.com/google/ExoPlayer/issues/9181)).
|
||||||
|
* Video:
|
||||||
|
* Fix bug in `MediaCodecVideoRenderer` that resulted in re-using a
|
||||||
|
released `Surface` when playing without an app-provided `Surface`
|
||||||
|
([#9476](https://github.com/google/ExoPlayer/issues/9476)).
|
||||||
|
* DRM:
|
||||||
|
* Log an error (instead of throwing `IllegalStateException`) when calling
|
||||||
|
`DefaultDrmSession#release()` on a fully released session
|
||||||
|
([#9392](https://github.com/google/ExoPlayer/issues/9392)).
|
||||||
* UI:
|
* UI:
|
||||||
* `SubtitleView` no longer implements `TextOutput`. `SubtitleView`
|
* `SubtitleView` no longer implements `TextOutput`. `SubtitleView`
|
||||||
implements `Player.Listener`, so can be registered to a player with
|
implements `Player.Listener`, so can be registered to a player with
|
||||||
@ -64,6 +68,7 @@
|
|||||||
* MP4: Avoid throwing `ArrayIndexOutOfBoundsException` when parsing
|
* MP4: Avoid throwing `ArrayIndexOutOfBoundsException` when parsing
|
||||||
invalid `colr` boxes produced by some device cameras
|
invalid `colr` boxes produced by some device cameras
|
||||||
([#9332](https://github.com/google/ExoPlayer/issues/9332)).
|
([#9332](https://github.com/google/ExoPlayer/issues/9332)).
|
||||||
|
* MP4: Parse HDR static metadata from the `clli` and `mdcv` boxes.
|
||||||
* TS: Correctly handle HEVC tracks with pixel aspect ratios other than 1.
|
* TS: Correctly handle HEVC tracks with pixel aspect ratios other than 1.
|
||||||
* TS: Map stream type 0x80 to H262
|
* TS: Map stream type 0x80 to H262
|
||||||
([#9472](https://github.com/google/ExoPlayer/issues/9472)).
|
([#9472](https://github.com/google/ExoPlayer/issues/9472)).
|
||||||
@ -73,7 +78,7 @@
|
|||||||
requirements for downloads to continue. In both cases, `DownloadService`
|
requirements for downloads to continue. In both cases, `DownloadService`
|
||||||
will now remain started and in the foreground whilst waiting for
|
will now remain started and in the foreground whilst waiting for
|
||||||
requirements to be met.
|
requirements to be met.
|
||||||
* Modify `DownlaodService` behavior when running on Android 12 and above.
|
* Modify `DownloadService` behavior when running on Android 12 and above.
|
||||||
See the "Android 12 compatibility" section above.
|
See the "Android 12 compatibility" section above.
|
||||||
* RTSP:
|
* RTSP:
|
||||||
* Support RFC4566 SDP attribute field grammar
|
* Support RFC4566 SDP attribute field grammar
|
||||||
@ -82,6 +87,12 @@
|
|||||||
* Populate `Format.sampleMimeType`, `width` and `height` for image
|
* Populate `Format.sampleMimeType`, `width` and `height` for image
|
||||||
`AdaptationSet` elements
|
`AdaptationSet` elements
|
||||||
([#9500](https://github.com/google/ExoPlayer/issues/9500)).
|
([#9500](https://github.com/google/ExoPlayer/issues/9500)).
|
||||||
|
* HLS:
|
||||||
|
* Fix rounding error in HLS playlists
|
||||||
|
([#9575](https://github.com/google/ExoPlayer/issues/9575)).
|
||||||
|
* Fix `NoSuchElementException` thrown when an HLS manifest declares
|
||||||
|
`#EXT-X-RENDITION-REPORT` at the beginning of the playlist
|
||||||
|
([#9592](https://github.com/google/ExoPlayer/issues/9592)).
|
||||||
* RTMP extension:
|
* RTMP extension:
|
||||||
* Upgrade to `io.antmedia:rtmp_client`, which does not rely on `jcenter()`
|
* Upgrade to `io.antmedia:rtmp_client`, which does not rely on `jcenter()`
|
||||||
([#9591](https://github.com/google/ExoPlayer/issues/9591)).
|
([#9591](https://github.com/google/ExoPlayer/issues/9591)).
|
||||||
@ -89,6 +100,9 @@
|
|||||||
* Rename
|
* Rename
|
||||||
`MediaSessionConnector.QueueNavigator#onCurrentWindowIndexChanged` to
|
`MediaSessionConnector.QueueNavigator#onCurrentWindowIndexChanged` to
|
||||||
`onCurrentMediaItemIndexChanged`.
|
`onCurrentMediaItemIndexChanged`.
|
||||||
|
* Transformer:
|
||||||
|
* Avoid sending a duplicate timestamp to the encoder with the end of
|
||||||
|
stream buffer.
|
||||||
* Remove deprecated symbols:
|
* Remove deprecated symbols:
|
||||||
* Remove `Renderer.VIDEO_SCALING_MODE_*` constants. Use identically named
|
* Remove `Renderer.VIDEO_SCALING_MODE_*` constants. Use identically named
|
||||||
constants in `C` instead.
|
constants in `C` instead.
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
project.ext {
|
project.ext {
|
||||||
// ExoPlayer version and version code.
|
// ExoPlayer version and version code.
|
||||||
releaseVersion = '2.15.1'
|
releaseVersion = '2.16.0'
|
||||||
releaseVersionCode = 2015001
|
releaseVersionCode = 2016000
|
||||||
minSdkVersion = 16
|
minSdkVersion = 16
|
||||||
appTargetSdkVersion = 29
|
appTargetSdkVersion = 29
|
||||||
// Upgrading this requires [Internal ref: b/193254928] to be fixed, or some
|
// Upgrading this requires [Internal ref: b/193254928] to be fixed, or some
|
||||||
|
@ -92,7 +92,7 @@ FFmpeg decoder name.
|
|||||||
## Standalone subtitle formats ##
|
## Standalone subtitle formats ##
|
||||||
|
|
||||||
ExoPlayer supports standalone subtitle files in a variety of formats. Subtitle
|
ExoPlayer supports standalone subtitle files in a variety of formats. Subtitle
|
||||||
files can be side-loaded as described on the [Media source page][].
|
files can be side-loaded as described on the [media items page][].
|
||||||
|
|
||||||
| Container format | Supported | MIME type |
|
| Container format | Supported | MIME type |
|
||||||
|---------------------------|:------------:|:----------|
|
|---------------------------|:------------:|:----------|
|
||||||
@ -101,7 +101,7 @@ files can be side-loaded as described on the [Media source page][].
|
|||||||
| SubRip | YES | MimeTypes.APPLICATION_SUBRIP |
|
| SubRip | YES | MimeTypes.APPLICATION_SUBRIP |
|
||||||
| SubStationAlpha (SSA/ASS) | YES | MimeTypes.TEXT_SSA |
|
| SubStationAlpha (SSA/ASS) | YES | MimeTypes.TEXT_SSA |
|
||||||
|
|
||||||
[Media source page]: {{ site.baseurl }}/media-sources.html#side-loading-a-subtitle-file
|
[media items page]: {{ site.baseurl }}/media-items.html#sideloading-subtitle-tracks
|
||||||
|
|
||||||
## HDR video playback ##
|
## HDR video playback ##
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ import com.google.android.exoplayer2.upstream.DataSchemeDataSource;
|
|||||||
import com.google.android.exoplayer2.upstream.DataSourceUtil;
|
import com.google.android.exoplayer2.upstream.DataSourceUtil;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -134,6 +135,35 @@ import java.util.Set;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Stores configuration for DAI ad playback. */
|
||||||
|
static final class DaiConfiguration {
|
||||||
|
|
||||||
|
public final AdErrorEvent.AdErrorListener applicationAdErrorListener;
|
||||||
|
public final boolean debugModeEnabled;
|
||||||
|
|
||||||
|
@Nullable public final List<CompanionAdSlot> companionAdSlots;
|
||||||
|
@Nullable public final AdEvent.AdEventListener applicationAdEventListener;
|
||||||
|
@Nullable public final VideoAdPlayer.VideoAdPlayerCallback applicationVideoAdPlayerCallback;
|
||||||
|
@Nullable public final ImaSdkSettings imaSdkSettings;
|
||||||
|
|
||||||
|
public DaiConfiguration(
|
||||||
|
AdErrorEvent.AdErrorListener applicationAdErrorListener,
|
||||||
|
@Nullable List<CompanionAdSlot> companionAdSlots,
|
||||||
|
@Nullable AdEvent.AdEventListener applicationAdEventListener,
|
||||||
|
@Nullable VideoAdPlayer.VideoAdPlayerCallback applicationVideoAdPlayerCallback,
|
||||||
|
@Nullable ImaSdkSettings imaSdkSettings,
|
||||||
|
boolean debugModeEnabled) {
|
||||||
|
|
||||||
|
this.applicationAdErrorListener = applicationAdErrorListener;
|
||||||
|
this.companionAdSlots =
|
||||||
|
companionAdSlots != null ? ImmutableList.copyOf(companionAdSlots) : null;
|
||||||
|
this.applicationAdEventListener = applicationAdEventListener;
|
||||||
|
this.applicationVideoAdPlayerCallback = applicationVideoAdPlayerCallback;
|
||||||
|
this.imaSdkSettings = imaSdkSettings;
|
||||||
|
this.debugModeEnabled = debugModeEnabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static final int TIMEOUT_UNSET = -1;
|
public static final int TIMEOUT_UNSET = -1;
|
||||||
public static final int BITRATE_UNSET = -1;
|
public static final int BITRATE_UNSET = -1;
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<manifest package="com.google.android.exoplayer2.ext.leanback">
|
<manifest xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="com.google.android.exoplayer2.ext.leanback"
|
||||||
|
tools:ignore="MissingLeanbackLauncher,ImpliedTouchscreenHardware,MissingLeanbackSupport">
|
||||||
<uses-sdk />
|
<uses-sdk />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
@ -27,11 +27,11 @@ public final class ExoPlayerLibraryInfo {
|
|||||||
|
|
||||||
/** The version of the library expressed as a string, for example "1.2.3". */
|
/** The version of the library expressed as a string, for example "1.2.3". */
|
||||||
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
|
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
|
||||||
public static final String VERSION = "2.15.1";
|
public static final String VERSION = "2.16.0";
|
||||||
|
|
||||||
/** The version of the library expressed as {@code TAG + "/" + VERSION}. */
|
/** The version of the library expressed as {@code TAG + "/" + VERSION}. */
|
||||||
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
||||||
public static final String VERSION_SLASHY = "ExoPlayerLib/2.15.1";
|
public static final String VERSION_SLASHY = "ExoPlayerLib/2.16.0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The version of the library expressed as an integer, for example 1002003.
|
* The version of the library expressed as an integer, for example 1002003.
|
||||||
@ -41,7 +41,7 @@ public final class ExoPlayerLibraryInfo {
|
|||||||
* integer version 123045006 (123-045-006).
|
* integer version 123045006 (123-045-006).
|
||||||
*/
|
*/
|
||||||
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
|
||||||
public static final int VERSION_INT = 2015001;
|
public static final int VERSION_INT = 2016000;
|
||||||
|
|
||||||
/** Whether the library was compiled with {@link Assertions} checks enabled. */
|
/** Whether the library was compiled with {@link Assertions} checks enabled. */
|
||||||
public static final boolean ASSERTIONS_ENABLED = true;
|
public static final boolean ASSERTIONS_ENABLED = true;
|
||||||
|
@ -891,7 +891,8 @@ public final class DownloadHelper {
|
|||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
DataSource.Factory dataSourceFactory,
|
DataSource.Factory dataSourceFactory,
|
||||||
@Nullable DrmSessionManager drmSessionManager) {
|
@Nullable DrmSessionManager drmSessionManager) {
|
||||||
return new DefaultMediaSourceFactory(dataSourceFactory, ExtractorsFactory.EMPTY)
|
return new DefaultMediaSourceFactory(
|
||||||
|
dataSourceFactory, ExtractorsFactory.EMPTY, /* serverSideDaiMediaSourceFactory= */ null)
|
||||||
.setDrmSessionManager(drmSessionManager)
|
.setDrmSessionManager(drmSessionManager)
|
||||||
.createMediaSource(mediaItem);
|
.createMediaSource(mediaItem);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import com.google.android.exoplayer2.upstream.DataSpec;
|
|||||||
import com.google.android.exoplayer2.upstream.DefaultDataSource;
|
import com.google.android.exoplayer2.upstream.DefaultDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||||
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
@ -119,6 +120,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
private final DataSource.Factory dataSourceFactory;
|
private final DataSource.Factory dataSourceFactory;
|
||||||
private final DelegateFactoryLoader delegateFactoryLoader;
|
private final DelegateFactoryLoader delegateFactoryLoader;
|
||||||
|
|
||||||
|
@Nullable private final MediaSourceFactory serverSideDaiMediaSourceFactory;
|
||||||
@Nullable private AdsLoaderProvider adsLoaderProvider;
|
@Nullable private AdsLoaderProvider adsLoaderProvider;
|
||||||
@Nullable private AdViewProvider adViewProvider;
|
@Nullable private AdViewProvider adViewProvider;
|
||||||
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
|
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
|
||||||
@ -146,7 +148,10 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
* its container.
|
* its container.
|
||||||
*/
|
*/
|
||||||
public DefaultMediaSourceFactory(Context context, ExtractorsFactory extractorsFactory) {
|
public DefaultMediaSourceFactory(Context context, ExtractorsFactory extractorsFactory) {
|
||||||
this(new DefaultDataSource.Factory(context), extractorsFactory);
|
this(
|
||||||
|
new DefaultDataSource.Factory(context),
|
||||||
|
extractorsFactory,
|
||||||
|
/* serverSideDaiMediaSourceFactory= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,7 +161,10 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
* for requesting media data.
|
* for requesting media data.
|
||||||
*/
|
*/
|
||||||
public DefaultMediaSourceFactory(DataSource.Factory dataSourceFactory) {
|
public DefaultMediaSourceFactory(DataSource.Factory dataSourceFactory) {
|
||||||
this(dataSourceFactory, new DefaultExtractorsFactory());
|
this(
|
||||||
|
dataSourceFactory,
|
||||||
|
new DefaultExtractorsFactory(),
|
||||||
|
/* serverSideDaiMediaSourceFactory= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,10 +174,17 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
* for requesting media data.
|
* for requesting media data.
|
||||||
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
|
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
|
||||||
* its container.
|
* its container.
|
||||||
|
* @param serverSideDaiMediaSourceFactory A {@link MediaSourceFactory} for creating server side
|
||||||
|
* inserted ad media sources.
|
||||||
*/
|
*/
|
||||||
public DefaultMediaSourceFactory(
|
public DefaultMediaSourceFactory(
|
||||||
DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) {
|
DataSource.Factory dataSourceFactory,
|
||||||
|
ExtractorsFactory extractorsFactory,
|
||||||
|
@Nullable MediaSourceFactory serverSideDaiMediaSourceFactory) {
|
||||||
this.dataSourceFactory = dataSourceFactory;
|
this.dataSourceFactory = dataSourceFactory;
|
||||||
|
// Temporary until factory registration is agreed upon.
|
||||||
|
this.serverSideDaiMediaSourceFactory = serverSideDaiMediaSourceFactory;
|
||||||
|
|
||||||
delegateFactoryLoader = new DelegateFactoryLoader(dataSourceFactory, extractorsFactory);
|
delegateFactoryLoader = new DelegateFactoryLoader(dataSourceFactory, extractorsFactory);
|
||||||
liveTargetOffsetMs = C.TIME_UNSET;
|
liveTargetOffsetMs = C.TIME_UNSET;
|
||||||
liveMinOffsetMs = C.TIME_UNSET;
|
liveMinOffsetMs = C.TIME_UNSET;
|
||||||
@ -333,7 +348,11 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaSource createMediaSource(MediaItem mediaItem) {
|
public MediaSource createMediaSource(MediaItem mediaItem) {
|
||||||
checkNotNull(mediaItem.localConfiguration);
|
Assertions.checkNotNull(mediaItem.localConfiguration);
|
||||||
|
@Nullable String scheme = mediaItem.localConfiguration.uri.getScheme();
|
||||||
|
if (scheme != null && scheme.equals("imadai")) {
|
||||||
|
return checkNotNull(serverSideDaiMediaSourceFactory).createMediaSource(mediaItem);
|
||||||
|
}
|
||||||
@C.ContentType
|
@C.ContentType
|
||||||
int type =
|
int type =
|
||||||
Util.inferContentTypeForUriAndMimeType(
|
Util.inferContentTypeForUriAndMimeType(
|
||||||
|
@ -410,6 +410,12 @@ import java.util.List;
|
|||||||
@SuppressWarnings("ConstantCaseForConstants")
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
public static final int TYPE_twos = 0x74776f73;
|
public static final int TYPE_twos = 0x74776f73;
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
|
public static final int TYPE_clli = 0x636c6c69;
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantCaseForConstants")
|
||||||
|
public static final int TYPE_mdcv = 0x6d646376;
|
||||||
|
|
||||||
public final int type;
|
public final int type;
|
||||||
|
|
||||||
public Atom(int type) {
|
public Atom(int type) {
|
||||||
|
@ -45,6 +45,8 @@ import com.google.android.exoplayer2.video.DolbyVisionConfig;
|
|||||||
import com.google.android.exoplayer2.video.HevcConfig;
|
import com.google.android.exoplayer2.video.HevcConfig;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -1061,6 +1063,8 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hdrStaticInfo is allocated using allocate() in allocateHdrStaticInfo().
|
||||||
|
@SuppressWarnings("ByteBufferBackingArray")
|
||||||
private static void parseVideoSampleEntry(
|
private static void parseVideoSampleEntry(
|
||||||
ParsableByteArray parent,
|
ParsableByteArray parent,
|
||||||
int atomType,
|
int atomType,
|
||||||
@ -1112,7 +1116,14 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
@Nullable String codecs = null;
|
@Nullable String codecs = null;
|
||||||
@Nullable byte[] projectionData = null;
|
@Nullable byte[] projectionData = null;
|
||||||
@C.StereoMode int stereoMode = Format.NO_VALUE;
|
@C.StereoMode int stereoMode = Format.NO_VALUE;
|
||||||
@Nullable ColorInfo colorInfo = null;
|
|
||||||
|
// HDR related metadata.
|
||||||
|
@C.ColorSpace int colorSpace = Format.NO_VALUE;
|
||||||
|
@C.ColorRange int colorRange = Format.NO_VALUE;
|
||||||
|
@C.ColorTransfer int colorTransfer = Format.NO_VALUE;
|
||||||
|
// The format of HDR static info is defined in CTA-861-G:2017, Table 45.
|
||||||
|
@Nullable ByteBuffer hdrStaticInfo = null;
|
||||||
|
|
||||||
while (childPosition - position < size) {
|
while (childPosition - position < size) {
|
||||||
parent.setPosition(childPosition);
|
parent.setPosition(childPosition);
|
||||||
int childStartPosition = parent.getPosition();
|
int childStartPosition = parent.getPosition();
|
||||||
@ -1157,6 +1168,43 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
} else if (childAtomType == Atom.TYPE_av1C) {
|
} else if (childAtomType == Atom.TYPE_av1C) {
|
||||||
ExtractorUtil.checkContainerInput(mimeType == null, /* message= */ null);
|
ExtractorUtil.checkContainerInput(mimeType == null, /* message= */ null);
|
||||||
mimeType = MimeTypes.VIDEO_AV1;
|
mimeType = MimeTypes.VIDEO_AV1;
|
||||||
|
} else if (childAtomType == Atom.TYPE_clli) {
|
||||||
|
if (hdrStaticInfo == null) {
|
||||||
|
hdrStaticInfo = allocateHdrStaticInfo();
|
||||||
|
}
|
||||||
|
// The contents of the clli box occupy the last 4 bytes of the HDR static info array. Note
|
||||||
|
// that each field is read in big endian and written in little endian.
|
||||||
|
hdrStaticInfo.position(21);
|
||||||
|
hdrStaticInfo.putShort(parent.readShort()); // max_content_light_level.
|
||||||
|
hdrStaticInfo.putShort(parent.readShort()); // max_pic_average_light_level.
|
||||||
|
} else if (childAtomType == Atom.TYPE_mdcv) {
|
||||||
|
if (hdrStaticInfo == null) {
|
||||||
|
hdrStaticInfo = allocateHdrStaticInfo();
|
||||||
|
}
|
||||||
|
// The contents of the mdcv box occupy 20 bytes after the first byte of the HDR static info
|
||||||
|
// array. Note that each field is read in big endian and written in little endian.
|
||||||
|
short displayPrimariesGX = parent.readShort();
|
||||||
|
short displayPrimariesGY = parent.readShort();
|
||||||
|
short displayPrimariesBX = parent.readShort();
|
||||||
|
short displayPrimariesBY = parent.readShort();
|
||||||
|
short displayPrimariesRX = parent.readShort();
|
||||||
|
short displayPrimariesRY = parent.readShort();
|
||||||
|
short whitePointX = parent.readShort();
|
||||||
|
short whitePointY = parent.readShort();
|
||||||
|
long maxDisplayMasteringLuminance = parent.readUnsignedInt();
|
||||||
|
long minDisplayMasteringLuminance = parent.readUnsignedInt();
|
||||||
|
|
||||||
|
hdrStaticInfo.position(1);
|
||||||
|
hdrStaticInfo.putShort(displayPrimariesRX);
|
||||||
|
hdrStaticInfo.putShort(displayPrimariesRY);
|
||||||
|
hdrStaticInfo.putShort(displayPrimariesGX);
|
||||||
|
hdrStaticInfo.putShort(displayPrimariesGY);
|
||||||
|
hdrStaticInfo.putShort(displayPrimariesBX);
|
||||||
|
hdrStaticInfo.putShort(displayPrimariesBY);
|
||||||
|
hdrStaticInfo.putShort(whitePointX);
|
||||||
|
hdrStaticInfo.putShort(whitePointY);
|
||||||
|
hdrStaticInfo.putShort((short) (maxDisplayMasteringLuminance / 10000));
|
||||||
|
hdrStaticInfo.putShort((short) (minDisplayMasteringLuminance / 10000));
|
||||||
} else if (childAtomType == Atom.TYPE_d263) {
|
} else if (childAtomType == Atom.TYPE_d263) {
|
||||||
ExtractorUtil.checkContainerInput(mimeType == null, /* message= */ null);
|
ExtractorUtil.checkContainerInput(mimeType == null, /* message= */ null);
|
||||||
mimeType = MimeTypes.VIDEO_H263;
|
mimeType = MimeTypes.VIDEO_H263;
|
||||||
@ -1211,12 +1259,10 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
// size=18): https://github.com/google/ExoPlayer/issues/9332
|
// size=18): https://github.com/google/ExoPlayer/issues/9332
|
||||||
boolean fullRangeFlag =
|
boolean fullRangeFlag =
|
||||||
childAtomSize == 19 && (parent.readUnsignedByte() & 0b10000000) != 0;
|
childAtomSize == 19 && (parent.readUnsignedByte() & 0b10000000) != 0;
|
||||||
colorInfo =
|
colorSpace = ColorInfo.isoColorPrimariesToColorSpace(colorPrimaries);
|
||||||
new ColorInfo(
|
colorRange = fullRangeFlag ? C.COLOR_RANGE_FULL : C.COLOR_RANGE_LIMITED;
|
||||||
ColorInfo.isoColorPrimariesToColorSpace(colorPrimaries),
|
colorTransfer =
|
||||||
fullRangeFlag ? C.COLOR_RANGE_FULL : C.COLOR_RANGE_LIMITED,
|
ColorInfo.isoTransferCharacteristicsToColorTransfer(transferCharacteristics);
|
||||||
ColorInfo.isoTransferCharacteristicsToColorTransfer(transferCharacteristics),
|
|
||||||
/* hdrStaticInfo= */ null);
|
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Unsupported color type: " + Atom.getAtomTypeString(colorType));
|
Log.w(TAG, "Unsupported color type: " + Atom.getAtomTypeString(colorType));
|
||||||
}
|
}
|
||||||
@ -1229,7 +1275,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
out.format =
|
Format.Builder formatBuilder =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setId(trackId)
|
.setId(trackId)
|
||||||
.setSampleMimeType(mimeType)
|
.setSampleMimeType(mimeType)
|
||||||
@ -1241,9 +1287,28 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
|
|||||||
.setProjectionData(projectionData)
|
.setProjectionData(projectionData)
|
||||||
.setStereoMode(stereoMode)
|
.setStereoMode(stereoMode)
|
||||||
.setInitializationData(initializationData)
|
.setInitializationData(initializationData)
|
||||||
.setDrmInitData(drmInitData)
|
.setDrmInitData(drmInitData);
|
||||||
.setColorInfo(colorInfo)
|
if (colorSpace != Format.NO_VALUE
|
||||||
.build();
|
|| colorRange != Format.NO_VALUE
|
||||||
|
|| colorTransfer != Format.NO_VALUE
|
||||||
|
|| hdrStaticInfo != null) {
|
||||||
|
// Note that if either mdcv or clli are missing, we leave the corresponding HDR static
|
||||||
|
// metadata bytes with value zero. See [Internal ref: b/194535665].
|
||||||
|
formatBuilder.setColorInfo(
|
||||||
|
new ColorInfo(
|
||||||
|
colorSpace,
|
||||||
|
colorRange,
|
||||||
|
colorTransfer,
|
||||||
|
hdrStaticInfo != null ? hdrStaticInfo.array() : null));
|
||||||
|
}
|
||||||
|
out.format = formatBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ByteBuffer allocateHdrStaticInfo() {
|
||||||
|
// For HDR static info, Android decoders expect a 25-byte array. The first byte is zero to
|
||||||
|
// represent Static Metadata Type 1, as per CTA-861-G:2017, Table 44. The following 24 bytes
|
||||||
|
// follow CTA-861-G:2017, Table 45.
|
||||||
|
return ByteBuffer.allocate(25).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseMetaDataSampleEntry(
|
private static void parseMetaDataSampleEntry(
|
||||||
|
@ -61,12 +61,18 @@ public final class WavExtractor implements Extractor {
|
|||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Target({ElementType.TYPE_USE})
|
@Target({ElementType.TYPE_USE})
|
||||||
@IntDef({STATE_READING_HEADER, STATE_SKIPPING_TO_SAMPLE_DATA, STATE_READING_SAMPLE_DATA})
|
@IntDef({
|
||||||
|
STATE_READING_FILE_TYPE,
|
||||||
|
STATE_READING_FORMAT,
|
||||||
|
STATE_SKIPPING_TO_SAMPLE_DATA,
|
||||||
|
STATE_READING_SAMPLE_DATA
|
||||||
|
})
|
||||||
private @interface State {}
|
private @interface State {}
|
||||||
|
|
||||||
private static final int STATE_READING_HEADER = 0;
|
private static final int STATE_READING_FILE_TYPE = 0;
|
||||||
private static final int STATE_SKIPPING_TO_SAMPLE_DATA = 1;
|
private static final int STATE_READING_FORMAT = 1;
|
||||||
private static final int STATE_READING_SAMPLE_DATA = 2;
|
private static final int STATE_SKIPPING_TO_SAMPLE_DATA = 2;
|
||||||
|
private static final int STATE_READING_SAMPLE_DATA = 3;
|
||||||
|
|
||||||
private @MonotonicNonNull ExtractorOutput extractorOutput;
|
private @MonotonicNonNull ExtractorOutput extractorOutput;
|
||||||
private @MonotonicNonNull TrackOutput trackOutput;
|
private @MonotonicNonNull TrackOutput trackOutput;
|
||||||
@ -76,14 +82,14 @@ public final class WavExtractor implements Extractor {
|
|||||||
private long dataEndPosition;
|
private long dataEndPosition;
|
||||||
|
|
||||||
public WavExtractor() {
|
public WavExtractor() {
|
||||||
state = STATE_READING_HEADER;
|
state = STATE_READING_FILE_TYPE;
|
||||||
dataStartPosition = C.POSITION_UNSET;
|
dataStartPosition = C.POSITION_UNSET;
|
||||||
dataEndPosition = C.POSITION_UNSET;
|
dataEndPosition = C.POSITION_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean sniff(ExtractorInput input) throws IOException {
|
public boolean sniff(ExtractorInput input) throws IOException {
|
||||||
return WavHeaderReader.peek(input) != null;
|
return WavHeaderReader.checkFileType(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -95,7 +101,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void seek(long position, long timeUs) {
|
public void seek(long position, long timeUs) {
|
||||||
state = position == 0 ? STATE_READING_HEADER : STATE_READING_SAMPLE_DATA;
|
state = position == 0 ? STATE_READING_FILE_TYPE : STATE_READING_SAMPLE_DATA;
|
||||||
if (outputWriter != null) {
|
if (outputWriter != null) {
|
||||||
outputWriter.reset(timeUs);
|
outputWriter.reset(timeUs);
|
||||||
}
|
}
|
||||||
@ -111,8 +117,11 @@ public final class WavExtractor implements Extractor {
|
|||||||
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException {
|
||||||
assertInitialized();
|
assertInitialized();
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_READING_HEADER:
|
case STATE_READING_FILE_TYPE:
|
||||||
readHeader(input);
|
readFileType(input);
|
||||||
|
return Extractor.RESULT_CONTINUE;
|
||||||
|
case STATE_READING_FORMAT:
|
||||||
|
readFormat(input);
|
||||||
return Extractor.RESULT_CONTINUE;
|
return Extractor.RESULT_CONTINUE;
|
||||||
case STATE_SKIPPING_TO_SAMPLE_DATA:
|
case STATE_SKIPPING_TO_SAMPLE_DATA:
|
||||||
skipToSampleData(input);
|
skipToSampleData(input);
|
||||||
@ -130,50 +139,54 @@ public final class WavExtractor implements Extractor {
|
|||||||
Util.castNonNull(extractorOutput);
|
Util.castNonNull(extractorOutput);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresNonNull({"extractorOutput", "trackOutput"})
|
private void readFileType(ExtractorInput input) throws IOException {
|
||||||
private void readHeader(ExtractorInput input) throws IOException {
|
|
||||||
Assertions.checkState(input.getPosition() == 0);
|
Assertions.checkState(input.getPosition() == 0);
|
||||||
if (dataStartPosition != C.POSITION_UNSET) {
|
if (dataStartPosition != C.POSITION_UNSET) {
|
||||||
input.skipFully(dataStartPosition);
|
input.skipFully(dataStartPosition);
|
||||||
state = STATE_READING_SAMPLE_DATA;
|
state = STATE_READING_SAMPLE_DATA;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WavHeader header = WavHeaderReader.peek(input);
|
if (!WavHeaderReader.checkFileType(input)) {
|
||||||
if (header == null) {
|
|
||||||
// Should only happen if the media wasn't sniffed.
|
// Should only happen if the media wasn't sniffed.
|
||||||
throw ParserException.createForMalformedContainer(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Unsupported or unrecognized wav header.", /* cause= */ null);
|
"Unsupported or unrecognized wav file type.", /* cause= */ null);
|
||||||
}
|
}
|
||||||
input.skipFully((int) (input.getPeekPosition() - input.getPosition()));
|
input.skipFully((int) (input.getPeekPosition() - input.getPosition()));
|
||||||
|
state = STATE_READING_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
if (header.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
@RequiresNonNull({"extractorOutput", "trackOutput"})
|
||||||
outputWriter = new ImaAdPcmOutputWriter(extractorOutput, trackOutput, header);
|
private void readFormat(ExtractorInput input) throws IOException {
|
||||||
} else if (header.formatType == WavUtil.TYPE_ALAW) {
|
WavFormat wavFormat = WavHeaderReader.readFormat(input);
|
||||||
|
if (wavFormat.formatType == WavUtil.TYPE_IMA_ADPCM) {
|
||||||
|
outputWriter = new ImaAdPcmOutputWriter(extractorOutput, trackOutput, wavFormat);
|
||||||
|
} else if (wavFormat.formatType == WavUtil.TYPE_ALAW) {
|
||||||
outputWriter =
|
outputWriter =
|
||||||
new PassthroughOutputWriter(
|
new PassthroughOutputWriter(
|
||||||
extractorOutput,
|
extractorOutput,
|
||||||
trackOutput,
|
trackOutput,
|
||||||
header,
|
wavFormat,
|
||||||
MimeTypes.AUDIO_ALAW,
|
MimeTypes.AUDIO_ALAW,
|
||||||
/* pcmEncoding= */ Format.NO_VALUE);
|
/* pcmEncoding= */ Format.NO_VALUE);
|
||||||
} else if (header.formatType == WavUtil.TYPE_MLAW) {
|
} else if (wavFormat.formatType == WavUtil.TYPE_MLAW) {
|
||||||
outputWriter =
|
outputWriter =
|
||||||
new PassthroughOutputWriter(
|
new PassthroughOutputWriter(
|
||||||
extractorOutput,
|
extractorOutput,
|
||||||
trackOutput,
|
trackOutput,
|
||||||
header,
|
wavFormat,
|
||||||
MimeTypes.AUDIO_MLAW,
|
MimeTypes.AUDIO_MLAW,
|
||||||
/* pcmEncoding= */ Format.NO_VALUE);
|
/* pcmEncoding= */ Format.NO_VALUE);
|
||||||
} else {
|
} else {
|
||||||
@C.PcmEncoding
|
@C.PcmEncoding
|
||||||
int pcmEncoding = WavUtil.getPcmEncodingForType(header.formatType, header.bitsPerSample);
|
int pcmEncoding =
|
||||||
|
WavUtil.getPcmEncodingForType(wavFormat.formatType, wavFormat.bitsPerSample);
|
||||||
if (pcmEncoding == C.ENCODING_INVALID) {
|
if (pcmEncoding == C.ENCODING_INVALID) {
|
||||||
throw ParserException.createForUnsupportedContainerFeature(
|
throw ParserException.createForUnsupportedContainerFeature(
|
||||||
"Unsupported WAV format type: " + header.formatType);
|
"Unsupported WAV format type: " + wavFormat.formatType);
|
||||||
}
|
}
|
||||||
outputWriter =
|
outputWriter =
|
||||||
new PassthroughOutputWriter(
|
new PassthroughOutputWriter(
|
||||||
extractorOutput, trackOutput, header, MimeTypes.AUDIO_RAW, pcmEncoding);
|
extractorOutput, trackOutput, wavFormat, MimeTypes.AUDIO_RAW, pcmEncoding);
|
||||||
}
|
}
|
||||||
state = STATE_SKIPPING_TO_SAMPLE_DATA;
|
state = STATE_SKIPPING_TO_SAMPLE_DATA;
|
||||||
}
|
}
|
||||||
@ -234,7 +247,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
|
|
||||||
private final ExtractorOutput extractorOutput;
|
private final ExtractorOutput extractorOutput;
|
||||||
private final TrackOutput trackOutput;
|
private final TrackOutput trackOutput;
|
||||||
private final WavHeader header;
|
private final WavFormat wavFormat;
|
||||||
private final Format format;
|
private final Format format;
|
||||||
/** The target size of each output sample, in bytes. */
|
/** The target size of each output sample, in bytes. */
|
||||||
private final int targetSampleSizeBytes;
|
private final int targetSampleSizeBytes;
|
||||||
@ -256,33 +269,33 @@ public final class WavExtractor implements Extractor {
|
|||||||
public PassthroughOutputWriter(
|
public PassthroughOutputWriter(
|
||||||
ExtractorOutput extractorOutput,
|
ExtractorOutput extractorOutput,
|
||||||
TrackOutput trackOutput,
|
TrackOutput trackOutput,
|
||||||
WavHeader header,
|
WavFormat wavFormat,
|
||||||
String mimeType,
|
String mimeType,
|
||||||
@C.PcmEncoding int pcmEncoding)
|
@C.PcmEncoding int pcmEncoding)
|
||||||
throws ParserException {
|
throws ParserException {
|
||||||
this.extractorOutput = extractorOutput;
|
this.extractorOutput = extractorOutput;
|
||||||
this.trackOutput = trackOutput;
|
this.trackOutput = trackOutput;
|
||||||
this.header = header;
|
this.wavFormat = wavFormat;
|
||||||
|
|
||||||
int bytesPerFrame = header.numChannels * header.bitsPerSample / 8;
|
int bytesPerFrame = wavFormat.numChannels * wavFormat.bitsPerSample / 8;
|
||||||
// Validate the header. Blocks are expected to correspond to single frames.
|
// Validate the WAV format. Blocks are expected to correspond to single frames.
|
||||||
if (header.blockSize != bytesPerFrame) {
|
if (wavFormat.blockSize != bytesPerFrame) {
|
||||||
throw ParserException.createForMalformedContainer(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Expected block size: " + bytesPerFrame + "; got: " + header.blockSize,
|
"Expected block size: " + bytesPerFrame + "; got: " + wavFormat.blockSize,
|
||||||
/* cause= */ null);
|
/* cause= */ null);
|
||||||
}
|
}
|
||||||
|
|
||||||
int constantBitrate = header.frameRateHz * bytesPerFrame * 8;
|
int constantBitrate = wavFormat.frameRateHz * bytesPerFrame * 8;
|
||||||
targetSampleSizeBytes =
|
targetSampleSizeBytes =
|
||||||
max(bytesPerFrame, header.frameRateHz * bytesPerFrame / TARGET_SAMPLES_PER_SECOND);
|
max(bytesPerFrame, wavFormat.frameRateHz * bytesPerFrame / TARGET_SAMPLES_PER_SECOND);
|
||||||
format =
|
format =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setSampleMimeType(mimeType)
|
.setSampleMimeType(mimeType)
|
||||||
.setAverageBitrate(constantBitrate)
|
.setAverageBitrate(constantBitrate)
|
||||||
.setPeakBitrate(constantBitrate)
|
.setPeakBitrate(constantBitrate)
|
||||||
.setMaxInputSize(targetSampleSizeBytes)
|
.setMaxInputSize(targetSampleSizeBytes)
|
||||||
.setChannelCount(header.numChannels)
|
.setChannelCount(wavFormat.numChannels)
|
||||||
.setSampleRate(header.frameRateHz)
|
.setSampleRate(wavFormat.frameRateHz)
|
||||||
.setPcmEncoding(pcmEncoding)
|
.setPcmEncoding(pcmEncoding)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@ -297,7 +310,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
@Override
|
@Override
|
||||||
public void init(int dataStartPosition, long dataEndPosition) {
|
public void init(int dataStartPosition, long dataEndPosition) {
|
||||||
extractorOutput.seekMap(
|
extractorOutput.seekMap(
|
||||||
new WavSeekMap(header, /* framesPerBlock= */ 1, dataStartPosition, dataEndPosition));
|
new WavSeekMap(wavFormat, /* framesPerBlock= */ 1, dataStartPosition, dataEndPosition));
|
||||||
trackOutput.format(format);
|
trackOutput.format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,13 +331,13 @@ public final class WavExtractor implements Extractor {
|
|||||||
// Write the corresponding sample metadata. Samples must be a whole number of frames. It's
|
// Write the corresponding sample metadata. Samples must be a whole number of frames. It's
|
||||||
// possible that the number of pending output bytes is not a whole number of frames if the
|
// possible that the number of pending output bytes is not a whole number of frames if the
|
||||||
// stream ended unexpectedly.
|
// stream ended unexpectedly.
|
||||||
int bytesPerFrame = header.blockSize;
|
int bytesPerFrame = wavFormat.blockSize;
|
||||||
int pendingFrames = pendingOutputBytes / bytesPerFrame;
|
int pendingFrames = pendingOutputBytes / bytesPerFrame;
|
||||||
if (pendingFrames > 0) {
|
if (pendingFrames > 0) {
|
||||||
long timeUs =
|
long timeUs =
|
||||||
startTimeUs
|
startTimeUs
|
||||||
+ Util.scaleLargeTimestamp(
|
+ Util.scaleLargeTimestamp(
|
||||||
outputFrameCount, C.MICROS_PER_SECOND, header.frameRateHz);
|
outputFrameCount, C.MICROS_PER_SECOND, wavFormat.frameRateHz);
|
||||||
int size = pendingFrames * bytesPerFrame;
|
int size = pendingFrames * bytesPerFrame;
|
||||||
int offset = pendingOutputBytes - size;
|
int offset = pendingOutputBytes - size;
|
||||||
trackOutput.sampleMetadata(
|
trackOutput.sampleMetadata(
|
||||||
@ -354,7 +367,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
|
|
||||||
private final ExtractorOutput extractorOutput;
|
private final ExtractorOutput extractorOutput;
|
||||||
private final TrackOutput trackOutput;
|
private final TrackOutput trackOutput;
|
||||||
private final WavHeader header;
|
private final WavFormat wavFormat;
|
||||||
|
|
||||||
/** Number of frames per block of the input (yet to be decoded) data. */
|
/** Number of frames per block of the input (yet to be decoded) data. */
|
||||||
private final int framesPerBlock;
|
private final int framesPerBlock;
|
||||||
@ -384,23 +397,26 @@ public final class WavExtractor implements Extractor {
|
|||||||
private long outputFrameCount;
|
private long outputFrameCount;
|
||||||
|
|
||||||
public ImaAdPcmOutputWriter(
|
public ImaAdPcmOutputWriter(
|
||||||
ExtractorOutput extractorOutput, TrackOutput trackOutput, WavHeader header)
|
ExtractorOutput extractorOutput, TrackOutput trackOutput, WavFormat wavFormat)
|
||||||
throws ParserException {
|
throws ParserException {
|
||||||
this.extractorOutput = extractorOutput;
|
this.extractorOutput = extractorOutput;
|
||||||
this.trackOutput = trackOutput;
|
this.trackOutput = trackOutput;
|
||||||
this.header = header;
|
this.wavFormat = wavFormat;
|
||||||
targetSampleSizeFrames = max(1, header.frameRateHz / TARGET_SAMPLES_PER_SECOND);
|
targetSampleSizeFrames = max(1, wavFormat.frameRateHz / TARGET_SAMPLES_PER_SECOND);
|
||||||
|
|
||||||
ParsableByteArray scratch = new ParsableByteArray(header.extraData);
|
ParsableByteArray scratch = new ParsableByteArray(wavFormat.extraData);
|
||||||
scratch.readLittleEndianUnsignedShort();
|
scratch.readLittleEndianUnsignedShort();
|
||||||
framesPerBlock = scratch.readLittleEndianUnsignedShort();
|
framesPerBlock = scratch.readLittleEndianUnsignedShort();
|
||||||
|
|
||||||
int numChannels = header.numChannels;
|
int numChannels = wavFormat.numChannels;
|
||||||
// Validate the header. This calculation is defined in "Microsoft Multimedia Standards Update
|
// Validate the WAV format. This calculation is defined in "Microsoft Multimedia Standards
|
||||||
|
// Update
|
||||||
// - New Multimedia Types and Data Techniques" (1994). See the "IMA ADPCM Wave Type" and "DVI
|
// - New Multimedia Types and Data Techniques" (1994). See the "IMA ADPCM Wave Type" and "DVI
|
||||||
// ADPCM Wave Type" sections, and the calculation of wSamplesPerBlock in the latter.
|
// ADPCM Wave Type" sections, and the calculation of wSamplesPerBlock in the latter.
|
||||||
int expectedFramesPerBlock =
|
int expectedFramesPerBlock =
|
||||||
(((header.blockSize - (4 * numChannels)) * 8) / (header.bitsPerSample * numChannels)) + 1;
|
(((wavFormat.blockSize - (4 * numChannels)) * 8)
|
||||||
|
/ (wavFormat.bitsPerSample * numChannels))
|
||||||
|
+ 1;
|
||||||
if (framesPerBlock != expectedFramesPerBlock) {
|
if (framesPerBlock != expectedFramesPerBlock) {
|
||||||
throw ParserException.createForMalformedContainer(
|
throw ParserException.createForMalformedContainer(
|
||||||
"Expected frames per block: " + expectedFramesPerBlock + "; got: " + framesPerBlock,
|
"Expected frames per block: " + expectedFramesPerBlock + "; got: " + framesPerBlock,
|
||||||
@ -410,22 +426,22 @@ public final class WavExtractor implements Extractor {
|
|||||||
// Calculate the number of blocks we'll need to decode to obtain an output sample of the
|
// Calculate the number of blocks we'll need to decode to obtain an output sample of the
|
||||||
// target sample size, and allocate suitably sized buffers for input and decoded data.
|
// target sample size, and allocate suitably sized buffers for input and decoded data.
|
||||||
int maxBlocksToDecode = Util.ceilDivide(targetSampleSizeFrames, framesPerBlock);
|
int maxBlocksToDecode = Util.ceilDivide(targetSampleSizeFrames, framesPerBlock);
|
||||||
inputData = new byte[maxBlocksToDecode * header.blockSize];
|
inputData = new byte[maxBlocksToDecode * wavFormat.blockSize];
|
||||||
decodedData =
|
decodedData =
|
||||||
new ParsableByteArray(
|
new ParsableByteArray(
|
||||||
maxBlocksToDecode * numOutputFramesToBytes(framesPerBlock, numChannels));
|
maxBlocksToDecode * numOutputFramesToBytes(framesPerBlock, numChannels));
|
||||||
|
|
||||||
// Create the format. We calculate the bitrate of the data before decoding, since this is the
|
// Create the format. We calculate the bitrate of the data before decoding, since this is the
|
||||||
// bitrate of the stream itself.
|
// bitrate of the stream itself.
|
||||||
int constantBitrate = header.frameRateHz * header.blockSize * 8 / framesPerBlock;
|
int constantBitrate = wavFormat.frameRateHz * wavFormat.blockSize * 8 / framesPerBlock;
|
||||||
format =
|
format =
|
||||||
new Format.Builder()
|
new Format.Builder()
|
||||||
.setSampleMimeType(MimeTypes.AUDIO_RAW)
|
.setSampleMimeType(MimeTypes.AUDIO_RAW)
|
||||||
.setAverageBitrate(constantBitrate)
|
.setAverageBitrate(constantBitrate)
|
||||||
.setPeakBitrate(constantBitrate)
|
.setPeakBitrate(constantBitrate)
|
||||||
.setMaxInputSize(numOutputFramesToBytes(targetSampleSizeFrames, numChannels))
|
.setMaxInputSize(numOutputFramesToBytes(targetSampleSizeFrames, numChannels))
|
||||||
.setChannelCount(header.numChannels)
|
.setChannelCount(wavFormat.numChannels)
|
||||||
.setSampleRate(header.frameRateHz)
|
.setSampleRate(wavFormat.frameRateHz)
|
||||||
.setPcmEncoding(C.ENCODING_PCM_16BIT)
|
.setPcmEncoding(C.ENCODING_PCM_16BIT)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
@ -441,7 +457,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
@Override
|
@Override
|
||||||
public void init(int dataStartPosition, long dataEndPosition) {
|
public void init(int dataStartPosition, long dataEndPosition) {
|
||||||
extractorOutput.seekMap(
|
extractorOutput.seekMap(
|
||||||
new WavSeekMap(header, framesPerBlock, dataStartPosition, dataEndPosition));
|
new WavSeekMap(wavFormat, framesPerBlock, dataStartPosition, dataEndPosition));
|
||||||
trackOutput.format(format);
|
trackOutput.format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +469,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
targetSampleSizeFrames - numOutputBytesToFrames(pendingOutputBytes);
|
targetSampleSizeFrames - numOutputBytesToFrames(pendingOutputBytes);
|
||||||
// Calculate the whole number of blocks that we need to decode to obtain this many frames.
|
// Calculate the whole number of blocks that we need to decode to obtain this many frames.
|
||||||
int blocksToDecode = Util.ceilDivide(targetFramesRemaining, framesPerBlock);
|
int blocksToDecode = Util.ceilDivide(targetFramesRemaining, framesPerBlock);
|
||||||
int targetReadBytes = blocksToDecode * header.blockSize;
|
int targetReadBytes = blocksToDecode * wavFormat.blockSize;
|
||||||
|
|
||||||
// Read input data until we've reached the target number of blocks, or the end of the data.
|
// Read input data until we've reached the target number of blocks, or the end of the data.
|
||||||
boolean endOfSampleData = bytesLeft == 0;
|
boolean endOfSampleData = bytesLeft == 0;
|
||||||
@ -467,11 +483,11 @@ public final class WavExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pendingBlockCount = pendingInputBytes / header.blockSize;
|
int pendingBlockCount = pendingInputBytes / wavFormat.blockSize;
|
||||||
if (pendingBlockCount > 0) {
|
if (pendingBlockCount > 0) {
|
||||||
// We have at least one whole block to decode.
|
// We have at least one whole block to decode.
|
||||||
decode(inputData, pendingBlockCount, decodedData);
|
decode(inputData, pendingBlockCount, decodedData);
|
||||||
pendingInputBytes -= pendingBlockCount * header.blockSize;
|
pendingInputBytes -= pendingBlockCount * wavFormat.blockSize;
|
||||||
|
|
||||||
// Write all of the decoded data to the track output.
|
// Write all of the decoded data to the track output.
|
||||||
int decodedDataSize = decodedData.limit();
|
int decodedDataSize = decodedData.limit();
|
||||||
@ -499,7 +515,8 @@ public final class WavExtractor implements Extractor {
|
|||||||
private void writeSampleMetadata(int sampleFrames) {
|
private void writeSampleMetadata(int sampleFrames) {
|
||||||
long timeUs =
|
long timeUs =
|
||||||
startTimeUs
|
startTimeUs
|
||||||
+ Util.scaleLargeTimestamp(outputFrameCount, C.MICROS_PER_SECOND, header.frameRateHz);
|
+ Util.scaleLargeTimestamp(
|
||||||
|
outputFrameCount, C.MICROS_PER_SECOND, wavFormat.frameRateHz);
|
||||||
int size = numOutputFramesToBytes(sampleFrames);
|
int size = numOutputFramesToBytes(sampleFrames);
|
||||||
int offset = pendingOutputBytes - size;
|
int offset = pendingOutputBytes - size;
|
||||||
trackOutput.sampleMetadata(
|
trackOutput.sampleMetadata(
|
||||||
@ -517,7 +534,7 @@ public final class WavExtractor implements Extractor {
|
|||||||
*/
|
*/
|
||||||
private void decode(byte[] input, int blockCount, ParsableByteArray output) {
|
private void decode(byte[] input, int blockCount, ParsableByteArray output) {
|
||||||
for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) {
|
||||||
for (int channelIndex = 0; channelIndex < header.numChannels; channelIndex++) {
|
for (int channelIndex = 0; channelIndex < wavFormat.numChannels; channelIndex++) {
|
||||||
decodeBlockForChannel(input, blockIndex, channelIndex, output.getData());
|
decodeBlockForChannel(input, blockIndex, channelIndex, output.getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,8 +545,8 @@ public final class WavExtractor implements Extractor {
|
|||||||
|
|
||||||
private void decodeBlockForChannel(
|
private void decodeBlockForChannel(
|
||||||
byte[] input, int blockIndex, int channelIndex, byte[] output) {
|
byte[] input, int blockIndex, int channelIndex, byte[] output) {
|
||||||
int blockSize = header.blockSize;
|
int blockSize = wavFormat.blockSize;
|
||||||
int numChannels = header.numChannels;
|
int numChannels = wavFormat.numChannels;
|
||||||
|
|
||||||
// The input data consists for a four byte header [Ci] for each of the N channels, followed
|
// The input data consists for a four byte header [Ci] for each of the N channels, followed
|
||||||
// by interleaved data segments [Ci-DATAj], each of which are four bytes long.
|
// by interleaved data segments [Ci-DATAj], each of which are four bytes long.
|
||||||
@ -590,11 +607,11 @@ public final class WavExtractor implements Extractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int numOutputBytesToFrames(int bytes) {
|
private int numOutputBytesToFrames(int bytes) {
|
||||||
return bytes / (2 * header.numChannels);
|
return bytes / (2 * wavFormat.numChannels);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int numOutputFramesToBytes(int frames) {
|
private int numOutputFramesToBytes(int frames) {
|
||||||
return numOutputFramesToBytes(frames, header.numChannels);
|
return numOutputFramesToBytes(frames, wavFormat.numChannels);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int numOutputFramesToBytes(int frames, int numChannels) {
|
private static int numOutputFramesToBytes(int frames, int numChannels) {
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.extractor.wav;
|
package com.google.android.exoplayer2.extractor.wav;
|
||||||
|
|
||||||
/** Header for a WAV file. */
|
/** Format information for a WAV file. */
|
||||||
/* package */ final class WavHeader {
|
/* package */ final class WavFormat {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The format type. Standard format types are the "WAVE form Registration Number" constants
|
* The format type. Standard format types are the "WAVE form Registration Number" constants
|
||||||
@ -33,10 +33,10 @@ package com.google.android.exoplayer2.extractor.wav;
|
|||||||
public final int blockSize;
|
public final int blockSize;
|
||||||
/** Bits per sample for a single channel. */
|
/** Bits per sample for a single channel. */
|
||||||
public final int bitsPerSample;
|
public final int bitsPerSample;
|
||||||
/** Extra data appended to the format chunk of the header. */
|
/** Extra data appended to the format chunk. */
|
||||||
public final byte[] extraData;
|
public final byte[] extraData;
|
||||||
|
|
||||||
public WavHeader(
|
public WavFormat(
|
||||||
int formatType,
|
int formatType,
|
||||||
int numChannels,
|
int numChannels,
|
||||||
int frameRateHz,
|
int frameRateHz,
|
@ -16,7 +16,6 @@
|
|||||||
package com.google.android.exoplayer2.extractor.wav;
|
package com.google.android.exoplayer2.extractor.wav;
|
||||||
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ParserException;
|
import com.google.android.exoplayer2.ParserException;
|
||||||
import com.google.android.exoplayer2.audio.WavUtil;
|
import com.google.android.exoplayer2.audio.WavUtil;
|
||||||
@ -27,45 +26,56 @@ import com.google.android.exoplayer2.util.ParsableByteArray;
|
|||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/** Reads a {@code WavHeader} from an input stream; supports resuming from input failures. */
|
/** Reads a WAV header from an input stream; supports resuming from input failures. */
|
||||||
/* package */ final class WavHeaderReader {
|
/* package */ final class WavHeaderReader {
|
||||||
|
|
||||||
private static final String TAG = "WavHeaderReader";
|
private static final String TAG = "WavHeaderReader";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Peeks and returns a {@code WavHeader}.
|
* Returns whether the given {@code input} starts with a RIFF chunk header, followed by a WAVE
|
||||||
|
* tag.
|
||||||
*
|
*
|
||||||
* @param input Input stream to peek the WAV header from.
|
* @param input The input stream to peek from. The position should point to the start of the
|
||||||
* @throws ParserException If the input file is an incorrect RIFF WAV.
|
* stream.
|
||||||
|
* @return Whether the given {@code input} starts with a RIFF chunk header, followed by a WAVE
|
||||||
|
* tag.
|
||||||
* @throws IOException If peeking from the input fails.
|
* @throws IOException If peeking from the input fails.
|
||||||
* @return A new {@code WavHeader} peeked from {@code input}, or null if the input is not a
|
|
||||||
* supported WAV format.
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
public static boolean checkFileType(ExtractorInput input) throws IOException {
|
||||||
public static WavHeader peek(ExtractorInput input) throws IOException {
|
ParsableByteArray scratch = new ParsableByteArray(ChunkHeader.SIZE_IN_BYTES);
|
||||||
Assertions.checkNotNull(input);
|
|
||||||
|
|
||||||
// Allocate a scratch buffer large enough to store the format chunk.
|
|
||||||
ParsableByteArray scratch = new ParsableByteArray(16);
|
|
||||||
|
|
||||||
// Attempt to read the RIFF chunk.
|
// Attempt to read the RIFF chunk.
|
||||||
ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
|
ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
|
||||||
if (chunkHeader.id != WavUtil.RIFF_FOURCC) {
|
if (chunkHeader.id != WavUtil.RIFF_FOURCC) {
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.peekFully(scratch.getData(), 0, 4);
|
input.peekFully(scratch.getData(), 0, 4);
|
||||||
scratch.setPosition(0);
|
scratch.setPosition(0);
|
||||||
int riffFormat = scratch.readInt();
|
int formType = scratch.readInt();
|
||||||
if (riffFormat != WavUtil.WAVE_FOURCC) {
|
if (formType != WavUtil.WAVE_FOURCC) {
|
||||||
Log.e(TAG, "Unsupported RIFF format: " + riffFormat);
|
Log.e(TAG, "Unsupported form type: " + formType);
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads and returns a {@code WavFormat}.
|
||||||
|
*
|
||||||
|
* @param input Input stream to read the WAV format from. The position should point to the byte
|
||||||
|
* following the WAVE tag.
|
||||||
|
* @throws IOException If reading from the input fails.
|
||||||
|
* @return A new {@code WavFormat} read from {@code input}.
|
||||||
|
*/
|
||||||
|
public static WavFormat readFormat(ExtractorInput input) throws IOException {
|
||||||
|
// Allocate a scratch buffer large enough to store the format chunk.
|
||||||
|
ParsableByteArray scratch = new ParsableByteArray(16);
|
||||||
|
|
||||||
// Skip chunks until we find the format chunk.
|
// Skip chunks until we find the format chunk.
|
||||||
chunkHeader = ChunkHeader.peek(input, scratch);
|
ChunkHeader chunkHeader = ChunkHeader.peek(input, scratch);
|
||||||
while (chunkHeader.id != WavUtil.FMT_FOURCC) {
|
while (chunkHeader.id != WavUtil.FMT_FOURCC) {
|
||||||
input.advancePeekPosition((int) chunkHeader.size);
|
input.skipFully(ChunkHeader.SIZE_IN_BYTES + (int) chunkHeader.size);
|
||||||
chunkHeader = ChunkHeader.peek(input, scratch);
|
chunkHeader = ChunkHeader.peek(input, scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +98,8 @@ import java.io.IOException;
|
|||||||
extraData = Util.EMPTY_BYTE_ARRAY;
|
extraData = Util.EMPTY_BYTE_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new WavHeader(
|
input.skipFully((int) (input.getPeekPosition() - input.getPosition()));
|
||||||
|
return new WavFormat(
|
||||||
audioFormatType,
|
audioFormatType,
|
||||||
numChannels,
|
numChannels,
|
||||||
frameRateHz,
|
frameRateHz,
|
||||||
@ -109,8 +120,6 @@ import java.io.IOException;
|
|||||||
* @throws IOException If reading from the input fails.
|
* @throws IOException If reading from the input fails.
|
||||||
*/
|
*/
|
||||||
public static Pair<Long, Long> skipToSampleData(ExtractorInput input) throws IOException {
|
public static Pair<Long, Long> skipToSampleData(ExtractorInput input) throws IOException {
|
||||||
Assertions.checkNotNull(input);
|
|
||||||
|
|
||||||
// Make sure the peek position is set to the read position before we peek the first header.
|
// Make sure the peek position is set to the read position before we peek the first header.
|
||||||
input.resetPeekPosition();
|
input.resetPeekPosition();
|
||||||
|
|
||||||
|
@ -22,18 +22,18 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
|
|
||||||
/* package */ final class WavSeekMap implements SeekMap {
|
/* package */ final class WavSeekMap implements SeekMap {
|
||||||
|
|
||||||
private final WavHeader wavHeader;
|
private final WavFormat wavFormat;
|
||||||
private final int framesPerBlock;
|
private final int framesPerBlock;
|
||||||
private final long firstBlockPosition;
|
private final long firstBlockPosition;
|
||||||
private final long blockCount;
|
private final long blockCount;
|
||||||
private final long durationUs;
|
private final long durationUs;
|
||||||
|
|
||||||
public WavSeekMap(
|
public WavSeekMap(
|
||||||
WavHeader wavHeader, int framesPerBlock, long dataStartPosition, long dataEndPosition) {
|
WavFormat wavFormat, int framesPerBlock, long dataStartPosition, long dataEndPosition) {
|
||||||
this.wavHeader = wavHeader;
|
this.wavFormat = wavFormat;
|
||||||
this.framesPerBlock = framesPerBlock;
|
this.framesPerBlock = framesPerBlock;
|
||||||
this.firstBlockPosition = dataStartPosition;
|
this.firstBlockPosition = dataStartPosition;
|
||||||
this.blockCount = (dataEndPosition - dataStartPosition) / wavHeader.blockSize;
|
this.blockCount = (dataEndPosition - dataStartPosition) / wavFormat.blockSize;
|
||||||
durationUs = blockIndexToTimeUs(blockCount);
|
durationUs = blockIndexToTimeUs(blockCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,17 +50,17 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
@Override
|
@Override
|
||||||
public SeekPoints getSeekPoints(long timeUs) {
|
public SeekPoints getSeekPoints(long timeUs) {
|
||||||
// Calculate the containing block index, constraining to valid indices.
|
// Calculate the containing block index, constraining to valid indices.
|
||||||
long blockIndex = (timeUs * wavHeader.frameRateHz) / (C.MICROS_PER_SECOND * framesPerBlock);
|
long blockIndex = (timeUs * wavFormat.frameRateHz) / (C.MICROS_PER_SECOND * framesPerBlock);
|
||||||
blockIndex = Util.constrainValue(blockIndex, 0, blockCount - 1);
|
blockIndex = Util.constrainValue(blockIndex, 0, blockCount - 1);
|
||||||
|
|
||||||
long seekPosition = firstBlockPosition + (blockIndex * wavHeader.blockSize);
|
long seekPosition = firstBlockPosition + (blockIndex * wavFormat.blockSize);
|
||||||
long seekTimeUs = blockIndexToTimeUs(blockIndex);
|
long seekTimeUs = blockIndexToTimeUs(blockIndex);
|
||||||
SeekPoint seekPoint = new SeekPoint(seekTimeUs, seekPosition);
|
SeekPoint seekPoint = new SeekPoint(seekTimeUs, seekPosition);
|
||||||
if (seekTimeUs >= timeUs || blockIndex == blockCount - 1) {
|
if (seekTimeUs >= timeUs || blockIndex == blockCount - 1) {
|
||||||
return new SeekPoints(seekPoint);
|
return new SeekPoints(seekPoint);
|
||||||
} else {
|
} else {
|
||||||
long secondBlockIndex = blockIndex + 1;
|
long secondBlockIndex = blockIndex + 1;
|
||||||
long secondSeekPosition = firstBlockPosition + (secondBlockIndex * wavHeader.blockSize);
|
long secondSeekPosition = firstBlockPosition + (secondBlockIndex * wavFormat.blockSize);
|
||||||
long secondSeekTimeUs = blockIndexToTimeUs(secondBlockIndex);
|
long secondSeekTimeUs = blockIndexToTimeUs(secondBlockIndex);
|
||||||
SeekPoint secondSeekPoint = new SeekPoint(secondSeekTimeUs, secondSeekPosition);
|
SeekPoint secondSeekPoint = new SeekPoint(secondSeekTimeUs, secondSeekPosition);
|
||||||
return new SeekPoints(seekPoint, secondSeekPoint);
|
return new SeekPoints(seekPoint, secondSeekPoint);
|
||||||
@ -69,6 +69,6 @@ import com.google.android.exoplayer2.util.Util;
|
|||||||
|
|
||||||
private long blockIndexToTimeUs(long blockIndex) {
|
private long blockIndexToTimeUs(long blockIndex) {
|
||||||
return Util.scaleLargeTimestamp(
|
return Util.scaleLargeTimestamp(
|
||||||
blockIndex * framesPerBlock, C.MICROS_PER_SECOND, wavHeader.frameRateHz);
|
blockIndex * framesPerBlock, C.MICROS_PER_SECOND, wavFormat.frameRateHz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,4 +119,10 @@ public final class Mp4ExtractorTest {
|
|||||||
ExtractorAsserts.assertBehavior(
|
ExtractorAsserts.assertBehavior(
|
||||||
Mp4Extractor::new, "media/mp4/sample_dthd.mp4", simulationConfig);
|
Mp4Extractor::new, "media/mp4/sample_dthd.mp4", simulationConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mp4SampleWithColrMdcvAndClli() throws Exception {
|
||||||
|
ExtractorAsserts.assertBehavior(
|
||||||
|
Mp4Extractor::new, "media/mp4/sample_with_colr_mdcv_and_clli.mp4", simulationConfig);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,9 @@ import java.io.DataInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -334,6 +337,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
/** Processes RTSP messages line-by-line. */
|
/** Processes RTSP messages line-by-line. */
|
||||||
private static final class MessageParser {
|
private static final class MessageParser {
|
||||||
|
|
||||||
|
@Documented
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef({STATE_READING_FIRST_LINE, STATE_READING_HEADER, STATE_READING_BODY})
|
@IntDef({STATE_READING_FIRST_LINE, STATE_READING_HEADER, STATE_READING_BODY})
|
||||||
@interface ReadingState {}
|
@interface ReadingState {}
|
||||||
|
|
||||||
|
@ -279,8 +279,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
int result = readSource(getFormatHolder(), decoderInputBuffer, /* readFlags= */ 0);
|
int result = readSource(getFormatHolder(), decoderInputBuffer, /* readFlags= */ 0);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case C.RESULT_BUFFER_READ:
|
case C.RESULT_BUFFER_READ:
|
||||||
decoderInputBuffer.timeUs -= streamOffsetUs;
|
|
||||||
mediaClock.updateTimeForTrackType(getTrackType(), decoderInputBuffer.timeUs);
|
mediaClock.updateTimeForTrackType(getTrackType(), decoderInputBuffer.timeUs);
|
||||||
|
decoderInputBuffer.timeUs -= streamOffsetUs;
|
||||||
decoderInputBuffer.flip();
|
decoderInputBuffer.flip();
|
||||||
decoder.queueInputBuffer(decoderInputBuffer);
|
decoder.queueInputBuffer(decoderInputBuffer);
|
||||||
return !decoderInputBuffer.isEndOfStream();
|
return !decoderInputBuffer.isEndOfStream();
|
||||||
@ -316,6 +316,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
|
|
||||||
private void queueEndOfStreamToEncoder(MediaCodecAdapterWrapper encoder) {
|
private void queueEndOfStreamToEncoder(MediaCodecAdapterWrapper encoder) {
|
||||||
checkState(checkNotNull(encoderInputBuffer.data).position() == 0);
|
checkState(checkNotNull(encoderInputBuffer.data).position() == 0);
|
||||||
|
encoderInputBuffer.timeUs = nextEncoderInputBufferTimeUs;
|
||||||
encoderInputBuffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
encoderInputBuffer.addFlag(C.BUFFER_FLAG_END_OF_STREAM);
|
||||||
encoderInputBuffer.flip();
|
encoderInputBuffer.flip();
|
||||||
// Queuing EOS should only occur with an empty buffer.
|
// Queuing EOS should only occur with an empty buffer.
|
||||||
|
@ -48,8 +48,7 @@ import com.google.android.exoplayer2.util.MimeTypes;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs)
|
protected void onStreamChanged(Format[] formats, long startPositionUs, long offsetUs) {
|
||||||
throws ExoPlaybackException {
|
|
||||||
this.streamOffsetUs = offsetUs;
|
this.streamOffsetUs = offsetUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +117,8 @@ import java.nio.ByteBuffer;
|
|||||||
muxerWrapper.endTrack(getTrackType());
|
muxerWrapper.endTrack(getTrackType());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
buffer.timeUs -= streamOffsetUs;
|
|
||||||
mediaClock.updateTimeForTrackType(getTrackType(), buffer.timeUs);
|
mediaClock.updateTimeForTrackType(getTrackType(), buffer.timeUs);
|
||||||
|
buffer.timeUs -= streamOffsetUs;
|
||||||
ByteBuffer data = checkNotNull(buffer.data);
|
ByteBuffer data = checkNotNull(buffer.data);
|
||||||
data.flip();
|
data.flip();
|
||||||
if (sampleTransformer != null) {
|
if (sampleTransformer != null) {
|
||||||
|
@ -320,8 +320,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||||||
case C.RESULT_FORMAT_READ:
|
case C.RESULT_FORMAT_READ:
|
||||||
throw new IllegalStateException("Format changes are not supported.");
|
throw new IllegalStateException("Format changes are not supported.");
|
||||||
case C.RESULT_BUFFER_READ:
|
case C.RESULT_BUFFER_READ:
|
||||||
decoderInputBuffer.timeUs -= streamOffsetUs;
|
|
||||||
mediaClock.updateTimeForTrackType(getTrackType(), decoderInputBuffer.timeUs);
|
mediaClock.updateTimeForTrackType(getTrackType(), decoderInputBuffer.timeUs);
|
||||||
|
decoderInputBuffer.timeUs -= streamOffsetUs;
|
||||||
ByteBuffer data = checkNotNull(decoderInputBuffer.data);
|
ByteBuffer data = checkNotNull(decoderInputBuffer.data);
|
||||||
data.flip();
|
data.flip();
|
||||||
decoder.queueInputBuffer(decoderInputBuffer);
|
decoder.queueInputBuffer(decoderInputBuffer);
|
||||||
|
454
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.0.dump
vendored
Normal file
454
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.0.dump
vendored
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 1022000
|
||||||
|
getPosition(0) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(511000) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1022000) = [[timeUs=0, position=48]]
|
||||||
|
numberOfTracks = 2
|
||||||
|
track 0:
|
||||||
|
total output bytes = 266091
|
||||||
|
sample count = 60
|
||||||
|
format 0:
|
||||||
|
id = 1
|
||||||
|
sampleMimeType = video/av01
|
||||||
|
maxInputSize = 144656
|
||||||
|
width = 1920
|
||||||
|
height = 1080
|
||||||
|
frameRate = 59.940056
|
||||||
|
colorInfo:
|
||||||
|
colorSpace = 6
|
||||||
|
colorRange = 2
|
||||||
|
colorTransfer = 6
|
||||||
|
hdrStaticInfo = length 25, hash 423AFC35
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1
|
||||||
|
data = length 144626, hash 7C021D5F
|
||||||
|
sample 1:
|
||||||
|
time = 16683
|
||||||
|
flags = 0
|
||||||
|
data = length 4018, hash FA5E79FA
|
||||||
|
sample 2:
|
||||||
|
time = 33366
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 3:
|
||||||
|
time = 50050
|
||||||
|
flags = 0
|
||||||
|
data = length 144, hash 4A868A2F
|
||||||
|
sample 4:
|
||||||
|
time = 66733
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 5:
|
||||||
|
time = 83416
|
||||||
|
flags = 0
|
||||||
|
data = length 342, hash 5A2E1C3C
|
||||||
|
sample 6:
|
||||||
|
time = 100100
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 7:
|
||||||
|
time = 116783
|
||||||
|
flags = 0
|
||||||
|
data = length 173, hash CFE014B3
|
||||||
|
sample 8:
|
||||||
|
time = 133466
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 9:
|
||||||
|
time = 150150
|
||||||
|
flags = 0
|
||||||
|
data = length 655, hash 3A7738B6
|
||||||
|
sample 10:
|
||||||
|
time = 166833
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 11:
|
||||||
|
time = 183516
|
||||||
|
flags = 0
|
||||||
|
data = length 208, hash E7D2035A
|
||||||
|
sample 12:
|
||||||
|
time = 200200
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 13:
|
||||||
|
time = 216883
|
||||||
|
flags = 0
|
||||||
|
data = length 385, hash 4D025B28
|
||||||
|
sample 14:
|
||||||
|
time = 233566
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 15:
|
||||||
|
time = 250250
|
||||||
|
flags = 0
|
||||||
|
data = length 192, hash CC0BD164
|
||||||
|
sample 16:
|
||||||
|
time = 266933
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5B0
|
||||||
|
sample 17:
|
||||||
|
time = 283616
|
||||||
|
flags = 0
|
||||||
|
data = length 36989, hash C213D35E
|
||||||
|
sample 18:
|
||||||
|
time = 300300
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 19:
|
||||||
|
time = 316983
|
||||||
|
flags = 0
|
||||||
|
data = length 213, hash 2BBA39D3
|
||||||
|
sample 20:
|
||||||
|
time = 333666
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 21:
|
||||||
|
time = 350350
|
||||||
|
flags = 0
|
||||||
|
data = length 474, hash 83D66E3F
|
||||||
|
sample 22:
|
||||||
|
time = 367033
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 23:
|
||||||
|
time = 383716
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash CF512AF0
|
||||||
|
sample 24:
|
||||||
|
time = 400400
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 25:
|
||||||
|
time = 417083
|
||||||
|
flags = 0
|
||||||
|
data = length 880, hash 8BFDE683
|
||||||
|
sample 26:
|
||||||
|
time = 433766
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 27:
|
||||||
|
time = 450450
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash 16B70503
|
||||||
|
sample 28:
|
||||||
|
time = 467133
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 29:
|
||||||
|
time = 483816
|
||||||
|
flags = 0
|
||||||
|
data = length 402, hash 51B5FAC9
|
||||||
|
sample 30:
|
||||||
|
time = 500500
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 31:
|
||||||
|
time = 517183
|
||||||
|
flags = 0
|
||||||
|
data = length 199, hash 12005069
|
||||||
|
sample 32:
|
||||||
|
time = 533866
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 33:
|
||||||
|
time = 550550
|
||||||
|
flags = 0
|
||||||
|
data = length 32362, hash F9FE31F7
|
||||||
|
sample 34:
|
||||||
|
time = 567233
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 35:
|
||||||
|
time = 583916
|
||||||
|
flags = 0
|
||||||
|
data = length 215, hash 2D4E3DC4
|
||||||
|
sample 36:
|
||||||
|
time = 600600
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 37:
|
||||||
|
time = 617283
|
||||||
|
flags = 0
|
||||||
|
data = length 450, hash C1A95E3
|
||||||
|
sample 38:
|
||||||
|
time = 633966
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 39:
|
||||||
|
time = 650650
|
||||||
|
flags = 0
|
||||||
|
data = length 221, hash 964386D9
|
||||||
|
sample 40:
|
||||||
|
time = 667333
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 41:
|
||||||
|
time = 684016
|
||||||
|
flags = 0
|
||||||
|
data = length 853, hash 2B9E0AAF
|
||||||
|
sample 42:
|
||||||
|
time = 700700
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 43:
|
||||||
|
time = 717383
|
||||||
|
flags = 0
|
||||||
|
data = length 236, hash 7E84BBAE
|
||||||
|
sample 44:
|
||||||
|
time = 734066
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 45:
|
||||||
|
time = 750750
|
||||||
|
flags = 0
|
||||||
|
data = length 419, hash 619235F2
|
||||||
|
sample 46:
|
||||||
|
time = 767433
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 47:
|
||||||
|
time = 784116
|
||||||
|
flags = 0
|
||||||
|
data = length 194, hash D386F352
|
||||||
|
sample 48:
|
||||||
|
time = 800800
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5A0
|
||||||
|
sample 49:
|
||||||
|
time = 817483
|
||||||
|
flags = 0
|
||||||
|
data = length 38679, hash 17E63FCD
|
||||||
|
sample 50:
|
||||||
|
time = 834166
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 51:
|
||||||
|
time = 850850
|
||||||
|
flags = 0
|
||||||
|
data = length 183, hash C8DD98E2
|
||||||
|
sample 52:
|
||||||
|
time = 867533
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 53:
|
||||||
|
time = 884216
|
||||||
|
flags = 0
|
||||||
|
data = length 457, hash 2B4E3476
|
||||||
|
sample 54:
|
||||||
|
time = 900900
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 55:
|
||||||
|
time = 917583
|
||||||
|
flags = 0
|
||||||
|
data = length 216, hash 7233540A
|
||||||
|
sample 56:
|
||||||
|
time = 934266
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 57:
|
||||||
|
time = 950950
|
||||||
|
flags = 0
|
||||||
|
data = length 894, hash 7319F313
|
||||||
|
sample 58:
|
||||||
|
time = 967633
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 59:
|
||||||
|
time = 984316
|
||||||
|
flags = 536870912
|
||||||
|
data = length 233, hash DE4DBE67
|
||||||
|
track 1:
|
||||||
|
total output bytes = 16638
|
||||||
|
sample count = 44
|
||||||
|
format 0:
|
||||||
|
id = 2
|
||||||
|
sampleMimeType = audio/mp4a-latm
|
||||||
|
codecs = mp4a.40.2
|
||||||
|
maxInputSize = 441
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 44100
|
||||||
|
language = und
|
||||||
|
metadata = entries=[TSSE: description=null: value=Lavf58.76.100]
|
||||||
|
initializationData:
|
||||||
|
data = length 16, hash CAA21BBF
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1
|
||||||
|
data = length 393, hash 706D1B6F
|
||||||
|
sample 1:
|
||||||
|
time = 23219
|
||||||
|
flags = 1
|
||||||
|
data = length 400, hash B48107D1
|
||||||
|
sample 2:
|
||||||
|
time = 46439
|
||||||
|
flags = 1
|
||||||
|
data = length 398, hash E5F4E9C1
|
||||||
|
sample 3:
|
||||||
|
time = 69659
|
||||||
|
flags = 1
|
||||||
|
data = length 400, hash 4317B40D
|
||||||
|
sample 4:
|
||||||
|
time = 92879
|
||||||
|
flags = 1
|
||||||
|
data = length 403, hash CB949D88
|
||||||
|
sample 5:
|
||||||
|
time = 116099
|
||||||
|
flags = 1
|
||||||
|
data = length 411, hash 616C8F82
|
||||||
|
sample 6:
|
||||||
|
time = 139319
|
||||||
|
flags = 1
|
||||||
|
data = length 392, hash 3BA50F06
|
||||||
|
sample 7:
|
||||||
|
time = 162539
|
||||||
|
flags = 1
|
||||||
|
data = length 401, hash 1C62F82C
|
||||||
|
sample 8:
|
||||||
|
time = 185759
|
||||||
|
flags = 1
|
||||||
|
data = length 400, hash 180FEA17
|
||||||
|
sample 9:
|
||||||
|
time = 208979
|
||||||
|
flags = 1
|
||||||
|
data = length 378, hash 2F6B0AE6
|
||||||
|
sample 10:
|
||||||
|
time = 232199
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash 6AE86D08
|
||||||
|
sample 11:
|
||||||
|
time = 255419
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash EF2FD9CC
|
||||||
|
sample 12:
|
||||||
|
time = 278639
|
||||||
|
flags = 1
|
||||||
|
data = length 374, hash 97B83243
|
||||||
|
sample 13:
|
||||||
|
time = 301859
|
||||||
|
flags = 1
|
||||||
|
data = length 382, hash 8BD6191C
|
||||||
|
sample 14:
|
||||||
|
time = 325079
|
||||||
|
flags = 1
|
||||||
|
data = length 393, hash D5F53221
|
||||||
|
sample 15:
|
||||||
|
time = 348299
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash 2437C16B
|
||||||
|
sample 16:
|
||||||
|
time = 371519
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash EE50108B
|
||||||
|
sample 17:
|
||||||
|
time = 394739
|
||||||
|
flags = 1
|
||||||
|
data = length 364, hash 9952E0FE
|
||||||
|
sample 18:
|
||||||
|
time = 417959
|
||||||
|
flags = 1
|
||||||
|
data = length 387, hash C4EC0E45
|
||||||
|
sample 19:
|
||||||
|
time = 441179
|
||||||
|
flags = 1
|
||||||
|
data = length 384, hash 7DFB424F
|
||||||
|
sample 20:
|
||||||
|
time = 464399
|
||||||
|
flags = 1
|
||||||
|
data = length 370, hash 28619E43
|
||||||
|
sample 21:
|
||||||
|
time = 487619
|
||||||
|
flags = 1
|
||||||
|
data = length 373, hash 440EB9E8
|
||||||
|
sample 22:
|
||||||
|
time = 510839
|
||||||
|
flags = 1
|
||||||
|
data = length 363, hash B7655913
|
||||||
|
sample 23:
|
||||||
|
time = 534058
|
||||||
|
flags = 1
|
||||||
|
data = length 362, hash A0690E92
|
||||||
|
sample 24:
|
||||||
|
time = 557278
|
||||||
|
flags = 1
|
||||||
|
data = length 377, hash 41BF1244
|
||||||
|
sample 25:
|
||||||
|
time = 580498
|
||||||
|
flags = 1
|
||||||
|
data = length 371, hash EE4124CD
|
||||||
|
sample 26:
|
||||||
|
time = 603718
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash 7A512168
|
||||||
|
sample 27:
|
||||||
|
time = 626938
|
||||||
|
flags = 1
|
||||||
|
data = length 370, hash ED00D55C
|
||||||
|
sample 28:
|
||||||
|
time = 650158
|
||||||
|
flags = 1
|
||||||
|
data = length 356, hash 43F4FFCA
|
||||||
|
sample 29:
|
||||||
|
time = 673378
|
||||||
|
flags = 1
|
||||||
|
data = length 373, hash 1950F38C
|
||||||
|
sample 30:
|
||||||
|
time = 696598
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 5F426A7A
|
||||||
|
sample 31:
|
||||||
|
time = 719818
|
||||||
|
flags = 1
|
||||||
|
data = length 371, hash FCC286D2
|
||||||
|
sample 32:
|
||||||
|
time = 743038
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash CF6F5DD9
|
||||||
|
sample 33:
|
||||||
|
time = 766258
|
||||||
|
flags = 1
|
||||||
|
data = length 386, hash 83E3B1E6
|
||||||
|
sample 34:
|
||||||
|
time = 789478
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash 5BDF670B
|
||||||
|
sample 35:
|
||||||
|
time = 812698
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash DC847E4D
|
||||||
|
sample 36:
|
||||||
|
time = 835918
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 8AC0C55C
|
||||||
|
sample 37:
|
||||||
|
time = 859138
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash C0D4BF4
|
||||||
|
sample 38:
|
||||||
|
time = 882358
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash 6C5284E2
|
||||||
|
sample 39:
|
||||||
|
time = 905578
|
||||||
|
flags = 1
|
||||||
|
data = length 380, hash BDFAB187
|
||||||
|
sample 40:
|
||||||
|
time = 928798
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash CEF87EB6
|
||||||
|
sample 41:
|
||||||
|
time = 952018
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash B0FF049B
|
||||||
|
sample 42:
|
||||||
|
time = 975238
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash BADD46E6
|
||||||
|
sample 43:
|
||||||
|
time = 998458
|
||||||
|
flags = 536870913
|
||||||
|
data = length 374, hash 6102A531
|
||||||
|
tracksEnded = true
|
398
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.1.dump
vendored
Normal file
398
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.1.dump
vendored
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 1022000
|
||||||
|
getPosition(0) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(511000) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1022000) = [[timeUs=0, position=48]]
|
||||||
|
numberOfTracks = 2
|
||||||
|
track 0:
|
||||||
|
total output bytes = 266091
|
||||||
|
sample count = 60
|
||||||
|
format 0:
|
||||||
|
id = 1
|
||||||
|
sampleMimeType = video/av01
|
||||||
|
maxInputSize = 144656
|
||||||
|
width = 1920
|
||||||
|
height = 1080
|
||||||
|
frameRate = 59.940056
|
||||||
|
colorInfo:
|
||||||
|
colorSpace = 6
|
||||||
|
colorRange = 2
|
||||||
|
colorTransfer = 6
|
||||||
|
hdrStaticInfo = length 25, hash 423AFC35
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1
|
||||||
|
data = length 144626, hash 7C021D5F
|
||||||
|
sample 1:
|
||||||
|
time = 16683
|
||||||
|
flags = 0
|
||||||
|
data = length 4018, hash FA5E79FA
|
||||||
|
sample 2:
|
||||||
|
time = 33366
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 3:
|
||||||
|
time = 50050
|
||||||
|
flags = 0
|
||||||
|
data = length 144, hash 4A868A2F
|
||||||
|
sample 4:
|
||||||
|
time = 66733
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 5:
|
||||||
|
time = 83416
|
||||||
|
flags = 0
|
||||||
|
data = length 342, hash 5A2E1C3C
|
||||||
|
sample 6:
|
||||||
|
time = 100100
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 7:
|
||||||
|
time = 116783
|
||||||
|
flags = 0
|
||||||
|
data = length 173, hash CFE014B3
|
||||||
|
sample 8:
|
||||||
|
time = 133466
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 9:
|
||||||
|
time = 150150
|
||||||
|
flags = 0
|
||||||
|
data = length 655, hash 3A7738B6
|
||||||
|
sample 10:
|
||||||
|
time = 166833
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 11:
|
||||||
|
time = 183516
|
||||||
|
flags = 0
|
||||||
|
data = length 208, hash E7D2035A
|
||||||
|
sample 12:
|
||||||
|
time = 200200
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 13:
|
||||||
|
time = 216883
|
||||||
|
flags = 0
|
||||||
|
data = length 385, hash 4D025B28
|
||||||
|
sample 14:
|
||||||
|
time = 233566
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 15:
|
||||||
|
time = 250250
|
||||||
|
flags = 0
|
||||||
|
data = length 192, hash CC0BD164
|
||||||
|
sample 16:
|
||||||
|
time = 266933
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5B0
|
||||||
|
sample 17:
|
||||||
|
time = 283616
|
||||||
|
flags = 0
|
||||||
|
data = length 36989, hash C213D35E
|
||||||
|
sample 18:
|
||||||
|
time = 300300
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 19:
|
||||||
|
time = 316983
|
||||||
|
flags = 0
|
||||||
|
data = length 213, hash 2BBA39D3
|
||||||
|
sample 20:
|
||||||
|
time = 333666
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 21:
|
||||||
|
time = 350350
|
||||||
|
flags = 0
|
||||||
|
data = length 474, hash 83D66E3F
|
||||||
|
sample 22:
|
||||||
|
time = 367033
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 23:
|
||||||
|
time = 383716
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash CF512AF0
|
||||||
|
sample 24:
|
||||||
|
time = 400400
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 25:
|
||||||
|
time = 417083
|
||||||
|
flags = 0
|
||||||
|
data = length 880, hash 8BFDE683
|
||||||
|
sample 26:
|
||||||
|
time = 433766
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 27:
|
||||||
|
time = 450450
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash 16B70503
|
||||||
|
sample 28:
|
||||||
|
time = 467133
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 29:
|
||||||
|
time = 483816
|
||||||
|
flags = 0
|
||||||
|
data = length 402, hash 51B5FAC9
|
||||||
|
sample 30:
|
||||||
|
time = 500500
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 31:
|
||||||
|
time = 517183
|
||||||
|
flags = 0
|
||||||
|
data = length 199, hash 12005069
|
||||||
|
sample 32:
|
||||||
|
time = 533866
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 33:
|
||||||
|
time = 550550
|
||||||
|
flags = 0
|
||||||
|
data = length 32362, hash F9FE31F7
|
||||||
|
sample 34:
|
||||||
|
time = 567233
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 35:
|
||||||
|
time = 583916
|
||||||
|
flags = 0
|
||||||
|
data = length 215, hash 2D4E3DC4
|
||||||
|
sample 36:
|
||||||
|
time = 600600
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 37:
|
||||||
|
time = 617283
|
||||||
|
flags = 0
|
||||||
|
data = length 450, hash C1A95E3
|
||||||
|
sample 38:
|
||||||
|
time = 633966
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 39:
|
||||||
|
time = 650650
|
||||||
|
flags = 0
|
||||||
|
data = length 221, hash 964386D9
|
||||||
|
sample 40:
|
||||||
|
time = 667333
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 41:
|
||||||
|
time = 684016
|
||||||
|
flags = 0
|
||||||
|
data = length 853, hash 2B9E0AAF
|
||||||
|
sample 42:
|
||||||
|
time = 700700
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 43:
|
||||||
|
time = 717383
|
||||||
|
flags = 0
|
||||||
|
data = length 236, hash 7E84BBAE
|
||||||
|
sample 44:
|
||||||
|
time = 734066
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 45:
|
||||||
|
time = 750750
|
||||||
|
flags = 0
|
||||||
|
data = length 419, hash 619235F2
|
||||||
|
sample 46:
|
||||||
|
time = 767433
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 47:
|
||||||
|
time = 784116
|
||||||
|
flags = 0
|
||||||
|
data = length 194, hash D386F352
|
||||||
|
sample 48:
|
||||||
|
time = 800800
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5A0
|
||||||
|
sample 49:
|
||||||
|
time = 817483
|
||||||
|
flags = 0
|
||||||
|
data = length 38679, hash 17E63FCD
|
||||||
|
sample 50:
|
||||||
|
time = 834166
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 51:
|
||||||
|
time = 850850
|
||||||
|
flags = 0
|
||||||
|
data = length 183, hash C8DD98E2
|
||||||
|
sample 52:
|
||||||
|
time = 867533
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 53:
|
||||||
|
time = 884216
|
||||||
|
flags = 0
|
||||||
|
data = length 457, hash 2B4E3476
|
||||||
|
sample 54:
|
||||||
|
time = 900900
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 55:
|
||||||
|
time = 917583
|
||||||
|
flags = 0
|
||||||
|
data = length 216, hash 7233540A
|
||||||
|
sample 56:
|
||||||
|
time = 934266
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 57:
|
||||||
|
time = 950950
|
||||||
|
flags = 0
|
||||||
|
data = length 894, hash 7319F313
|
||||||
|
sample 58:
|
||||||
|
time = 967633
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 59:
|
||||||
|
time = 984316
|
||||||
|
flags = 536870912
|
||||||
|
data = length 233, hash DE4DBE67
|
||||||
|
track 1:
|
||||||
|
total output bytes = 11156
|
||||||
|
sample count = 30
|
||||||
|
format 0:
|
||||||
|
id = 2
|
||||||
|
sampleMimeType = audio/mp4a-latm
|
||||||
|
codecs = mp4a.40.2
|
||||||
|
maxInputSize = 441
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 44100
|
||||||
|
language = und
|
||||||
|
metadata = entries=[TSSE: description=null: value=Lavf58.76.100]
|
||||||
|
initializationData:
|
||||||
|
data = length 16, hash CAA21BBF
|
||||||
|
sample 0:
|
||||||
|
time = 325079
|
||||||
|
flags = 1
|
||||||
|
data = length 393, hash D5F53221
|
||||||
|
sample 1:
|
||||||
|
time = 348299
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash 2437C16B
|
||||||
|
sample 2:
|
||||||
|
time = 371519
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash EE50108B
|
||||||
|
sample 3:
|
||||||
|
time = 394739
|
||||||
|
flags = 1
|
||||||
|
data = length 364, hash 9952E0FE
|
||||||
|
sample 4:
|
||||||
|
time = 417959
|
||||||
|
flags = 1
|
||||||
|
data = length 387, hash C4EC0E45
|
||||||
|
sample 5:
|
||||||
|
time = 441179
|
||||||
|
flags = 1
|
||||||
|
data = length 384, hash 7DFB424F
|
||||||
|
sample 6:
|
||||||
|
time = 464399
|
||||||
|
flags = 1
|
||||||
|
data = length 370, hash 28619E43
|
||||||
|
sample 7:
|
||||||
|
time = 487619
|
||||||
|
flags = 1
|
||||||
|
data = length 373, hash 440EB9E8
|
||||||
|
sample 8:
|
||||||
|
time = 510839
|
||||||
|
flags = 1
|
||||||
|
data = length 363, hash B7655913
|
||||||
|
sample 9:
|
||||||
|
time = 534058
|
||||||
|
flags = 1
|
||||||
|
data = length 362, hash A0690E92
|
||||||
|
sample 10:
|
||||||
|
time = 557278
|
||||||
|
flags = 1
|
||||||
|
data = length 377, hash 41BF1244
|
||||||
|
sample 11:
|
||||||
|
time = 580498
|
||||||
|
flags = 1
|
||||||
|
data = length 371, hash EE4124CD
|
||||||
|
sample 12:
|
||||||
|
time = 603718
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash 7A512168
|
||||||
|
sample 13:
|
||||||
|
time = 626938
|
||||||
|
flags = 1
|
||||||
|
data = length 370, hash ED00D55C
|
||||||
|
sample 14:
|
||||||
|
time = 650158
|
||||||
|
flags = 1
|
||||||
|
data = length 356, hash 43F4FFCA
|
||||||
|
sample 15:
|
||||||
|
time = 673378
|
||||||
|
flags = 1
|
||||||
|
data = length 373, hash 1950F38C
|
||||||
|
sample 16:
|
||||||
|
time = 696598
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 5F426A7A
|
||||||
|
sample 17:
|
||||||
|
time = 719818
|
||||||
|
flags = 1
|
||||||
|
data = length 371, hash FCC286D2
|
||||||
|
sample 18:
|
||||||
|
time = 743038
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash CF6F5DD9
|
||||||
|
sample 19:
|
||||||
|
time = 766258
|
||||||
|
flags = 1
|
||||||
|
data = length 386, hash 83E3B1E6
|
||||||
|
sample 20:
|
||||||
|
time = 789478
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash 5BDF670B
|
||||||
|
sample 21:
|
||||||
|
time = 812698
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash DC847E4D
|
||||||
|
sample 22:
|
||||||
|
time = 835918
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 8AC0C55C
|
||||||
|
sample 23:
|
||||||
|
time = 859138
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash C0D4BF4
|
||||||
|
sample 24:
|
||||||
|
time = 882358
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash 6C5284E2
|
||||||
|
sample 25:
|
||||||
|
time = 905578
|
||||||
|
flags = 1
|
||||||
|
data = length 380, hash BDFAB187
|
||||||
|
sample 26:
|
||||||
|
time = 928798
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash CEF87EB6
|
||||||
|
sample 27:
|
||||||
|
time = 952018
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash B0FF049B
|
||||||
|
sample 28:
|
||||||
|
time = 975238
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash BADD46E6
|
||||||
|
sample 29:
|
||||||
|
time = 998458
|
||||||
|
flags = 536870913
|
||||||
|
data = length 374, hash 6102A531
|
||||||
|
tracksEnded = true
|
338
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.2.dump
vendored
Normal file
338
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.2.dump
vendored
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 1022000
|
||||||
|
getPosition(0) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(511000) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1022000) = [[timeUs=0, position=48]]
|
||||||
|
numberOfTracks = 2
|
||||||
|
track 0:
|
||||||
|
total output bytes = 266091
|
||||||
|
sample count = 60
|
||||||
|
format 0:
|
||||||
|
id = 1
|
||||||
|
sampleMimeType = video/av01
|
||||||
|
maxInputSize = 144656
|
||||||
|
width = 1920
|
||||||
|
height = 1080
|
||||||
|
frameRate = 59.940056
|
||||||
|
colorInfo:
|
||||||
|
colorSpace = 6
|
||||||
|
colorRange = 2
|
||||||
|
colorTransfer = 6
|
||||||
|
hdrStaticInfo = length 25, hash 423AFC35
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1
|
||||||
|
data = length 144626, hash 7C021D5F
|
||||||
|
sample 1:
|
||||||
|
time = 16683
|
||||||
|
flags = 0
|
||||||
|
data = length 4018, hash FA5E79FA
|
||||||
|
sample 2:
|
||||||
|
time = 33366
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 3:
|
||||||
|
time = 50050
|
||||||
|
flags = 0
|
||||||
|
data = length 144, hash 4A868A2F
|
||||||
|
sample 4:
|
||||||
|
time = 66733
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 5:
|
||||||
|
time = 83416
|
||||||
|
flags = 0
|
||||||
|
data = length 342, hash 5A2E1C3C
|
||||||
|
sample 6:
|
||||||
|
time = 100100
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 7:
|
||||||
|
time = 116783
|
||||||
|
flags = 0
|
||||||
|
data = length 173, hash CFE014B3
|
||||||
|
sample 8:
|
||||||
|
time = 133466
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 9:
|
||||||
|
time = 150150
|
||||||
|
flags = 0
|
||||||
|
data = length 655, hash 3A7738B6
|
||||||
|
sample 10:
|
||||||
|
time = 166833
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 11:
|
||||||
|
time = 183516
|
||||||
|
flags = 0
|
||||||
|
data = length 208, hash E7D2035A
|
||||||
|
sample 12:
|
||||||
|
time = 200200
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 13:
|
||||||
|
time = 216883
|
||||||
|
flags = 0
|
||||||
|
data = length 385, hash 4D025B28
|
||||||
|
sample 14:
|
||||||
|
time = 233566
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 15:
|
||||||
|
time = 250250
|
||||||
|
flags = 0
|
||||||
|
data = length 192, hash CC0BD164
|
||||||
|
sample 16:
|
||||||
|
time = 266933
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5B0
|
||||||
|
sample 17:
|
||||||
|
time = 283616
|
||||||
|
flags = 0
|
||||||
|
data = length 36989, hash C213D35E
|
||||||
|
sample 18:
|
||||||
|
time = 300300
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 19:
|
||||||
|
time = 316983
|
||||||
|
flags = 0
|
||||||
|
data = length 213, hash 2BBA39D3
|
||||||
|
sample 20:
|
||||||
|
time = 333666
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 21:
|
||||||
|
time = 350350
|
||||||
|
flags = 0
|
||||||
|
data = length 474, hash 83D66E3F
|
||||||
|
sample 22:
|
||||||
|
time = 367033
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 23:
|
||||||
|
time = 383716
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash CF512AF0
|
||||||
|
sample 24:
|
||||||
|
time = 400400
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 25:
|
||||||
|
time = 417083
|
||||||
|
flags = 0
|
||||||
|
data = length 880, hash 8BFDE683
|
||||||
|
sample 26:
|
||||||
|
time = 433766
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 27:
|
||||||
|
time = 450450
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash 16B70503
|
||||||
|
sample 28:
|
||||||
|
time = 467133
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 29:
|
||||||
|
time = 483816
|
||||||
|
flags = 0
|
||||||
|
data = length 402, hash 51B5FAC9
|
||||||
|
sample 30:
|
||||||
|
time = 500500
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 31:
|
||||||
|
time = 517183
|
||||||
|
flags = 0
|
||||||
|
data = length 199, hash 12005069
|
||||||
|
sample 32:
|
||||||
|
time = 533866
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 33:
|
||||||
|
time = 550550
|
||||||
|
flags = 0
|
||||||
|
data = length 32362, hash F9FE31F7
|
||||||
|
sample 34:
|
||||||
|
time = 567233
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 35:
|
||||||
|
time = 583916
|
||||||
|
flags = 0
|
||||||
|
data = length 215, hash 2D4E3DC4
|
||||||
|
sample 36:
|
||||||
|
time = 600600
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 37:
|
||||||
|
time = 617283
|
||||||
|
flags = 0
|
||||||
|
data = length 450, hash C1A95E3
|
||||||
|
sample 38:
|
||||||
|
time = 633966
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 39:
|
||||||
|
time = 650650
|
||||||
|
flags = 0
|
||||||
|
data = length 221, hash 964386D9
|
||||||
|
sample 40:
|
||||||
|
time = 667333
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 41:
|
||||||
|
time = 684016
|
||||||
|
flags = 0
|
||||||
|
data = length 853, hash 2B9E0AAF
|
||||||
|
sample 42:
|
||||||
|
time = 700700
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 43:
|
||||||
|
time = 717383
|
||||||
|
flags = 0
|
||||||
|
data = length 236, hash 7E84BBAE
|
||||||
|
sample 44:
|
||||||
|
time = 734066
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 45:
|
||||||
|
time = 750750
|
||||||
|
flags = 0
|
||||||
|
data = length 419, hash 619235F2
|
||||||
|
sample 46:
|
||||||
|
time = 767433
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 47:
|
||||||
|
time = 784116
|
||||||
|
flags = 0
|
||||||
|
data = length 194, hash D386F352
|
||||||
|
sample 48:
|
||||||
|
time = 800800
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5A0
|
||||||
|
sample 49:
|
||||||
|
time = 817483
|
||||||
|
flags = 0
|
||||||
|
data = length 38679, hash 17E63FCD
|
||||||
|
sample 50:
|
||||||
|
time = 834166
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 51:
|
||||||
|
time = 850850
|
||||||
|
flags = 0
|
||||||
|
data = length 183, hash C8DD98E2
|
||||||
|
sample 52:
|
||||||
|
time = 867533
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 53:
|
||||||
|
time = 884216
|
||||||
|
flags = 0
|
||||||
|
data = length 457, hash 2B4E3476
|
||||||
|
sample 54:
|
||||||
|
time = 900900
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 55:
|
||||||
|
time = 917583
|
||||||
|
flags = 0
|
||||||
|
data = length 216, hash 7233540A
|
||||||
|
sample 56:
|
||||||
|
time = 934266
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 57:
|
||||||
|
time = 950950
|
||||||
|
flags = 0
|
||||||
|
data = length 894, hash 7319F313
|
||||||
|
sample 58:
|
||||||
|
time = 967633
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 59:
|
||||||
|
time = 984316
|
||||||
|
flags = 536870912
|
||||||
|
data = length 233, hash DE4DBE67
|
||||||
|
track 1:
|
||||||
|
total output bytes = 5567
|
||||||
|
sample count = 15
|
||||||
|
format 0:
|
||||||
|
id = 2
|
||||||
|
sampleMimeType = audio/mp4a-latm
|
||||||
|
codecs = mp4a.40.2
|
||||||
|
maxInputSize = 441
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 44100
|
||||||
|
language = und
|
||||||
|
metadata = entries=[TSSE: description=null: value=Lavf58.76.100]
|
||||||
|
initializationData:
|
||||||
|
data = length 16, hash CAA21BBF
|
||||||
|
sample 0:
|
||||||
|
time = 673378
|
||||||
|
flags = 1
|
||||||
|
data = length 373, hash 1950F38C
|
||||||
|
sample 1:
|
||||||
|
time = 696598
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 5F426A7A
|
||||||
|
sample 2:
|
||||||
|
time = 719818
|
||||||
|
flags = 1
|
||||||
|
data = length 371, hash FCC286D2
|
||||||
|
sample 3:
|
||||||
|
time = 743038
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash CF6F5DD9
|
||||||
|
sample 4:
|
||||||
|
time = 766258
|
||||||
|
flags = 1
|
||||||
|
data = length 386, hash 83E3B1E6
|
||||||
|
sample 5:
|
||||||
|
time = 789478
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash 5BDF670B
|
||||||
|
sample 6:
|
||||||
|
time = 812698
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash DC847E4D
|
||||||
|
sample 7:
|
||||||
|
time = 835918
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 8AC0C55C
|
||||||
|
sample 8:
|
||||||
|
time = 859138
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash C0D4BF4
|
||||||
|
sample 9:
|
||||||
|
time = 882358
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash 6C5284E2
|
||||||
|
sample 10:
|
||||||
|
time = 905578
|
||||||
|
flags = 1
|
||||||
|
data = length 380, hash BDFAB187
|
||||||
|
sample 11:
|
||||||
|
time = 928798
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash CEF87EB6
|
||||||
|
sample 12:
|
||||||
|
time = 952018
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash B0FF049B
|
||||||
|
sample 13:
|
||||||
|
time = 975238
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash BADD46E6
|
||||||
|
sample 14:
|
||||||
|
time = 998458
|
||||||
|
flags = 536870913
|
||||||
|
data = length 374, hash 6102A531
|
||||||
|
tracksEnded = true
|
282
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.3.dump
vendored
Normal file
282
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.3.dump
vendored
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 1022000
|
||||||
|
getPosition(0) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(511000) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1022000) = [[timeUs=0, position=48]]
|
||||||
|
numberOfTracks = 2
|
||||||
|
track 0:
|
||||||
|
total output bytes = 266091
|
||||||
|
sample count = 60
|
||||||
|
format 0:
|
||||||
|
id = 1
|
||||||
|
sampleMimeType = video/av01
|
||||||
|
maxInputSize = 144656
|
||||||
|
width = 1920
|
||||||
|
height = 1080
|
||||||
|
frameRate = 59.940056
|
||||||
|
colorInfo:
|
||||||
|
colorSpace = 6
|
||||||
|
colorRange = 2
|
||||||
|
colorTransfer = 6
|
||||||
|
hdrStaticInfo = length 25, hash 423AFC35
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1
|
||||||
|
data = length 144626, hash 7C021D5F
|
||||||
|
sample 1:
|
||||||
|
time = 16683
|
||||||
|
flags = 0
|
||||||
|
data = length 4018, hash FA5E79FA
|
||||||
|
sample 2:
|
||||||
|
time = 33366
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 3:
|
||||||
|
time = 50050
|
||||||
|
flags = 0
|
||||||
|
data = length 144, hash 4A868A2F
|
||||||
|
sample 4:
|
||||||
|
time = 66733
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 5:
|
||||||
|
time = 83416
|
||||||
|
flags = 0
|
||||||
|
data = length 342, hash 5A2E1C3C
|
||||||
|
sample 6:
|
||||||
|
time = 100100
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 7:
|
||||||
|
time = 116783
|
||||||
|
flags = 0
|
||||||
|
data = length 173, hash CFE014B3
|
||||||
|
sample 8:
|
||||||
|
time = 133466
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 9:
|
||||||
|
time = 150150
|
||||||
|
flags = 0
|
||||||
|
data = length 655, hash 3A7738B6
|
||||||
|
sample 10:
|
||||||
|
time = 166833
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 11:
|
||||||
|
time = 183516
|
||||||
|
flags = 0
|
||||||
|
data = length 208, hash E7D2035A
|
||||||
|
sample 12:
|
||||||
|
time = 200200
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 13:
|
||||||
|
time = 216883
|
||||||
|
flags = 0
|
||||||
|
data = length 385, hash 4D025B28
|
||||||
|
sample 14:
|
||||||
|
time = 233566
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 15:
|
||||||
|
time = 250250
|
||||||
|
flags = 0
|
||||||
|
data = length 192, hash CC0BD164
|
||||||
|
sample 16:
|
||||||
|
time = 266933
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5B0
|
||||||
|
sample 17:
|
||||||
|
time = 283616
|
||||||
|
flags = 0
|
||||||
|
data = length 36989, hash C213D35E
|
||||||
|
sample 18:
|
||||||
|
time = 300300
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 19:
|
||||||
|
time = 316983
|
||||||
|
flags = 0
|
||||||
|
data = length 213, hash 2BBA39D3
|
||||||
|
sample 20:
|
||||||
|
time = 333666
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 21:
|
||||||
|
time = 350350
|
||||||
|
flags = 0
|
||||||
|
data = length 474, hash 83D66E3F
|
||||||
|
sample 22:
|
||||||
|
time = 367033
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 23:
|
||||||
|
time = 383716
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash CF512AF0
|
||||||
|
sample 24:
|
||||||
|
time = 400400
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 25:
|
||||||
|
time = 417083
|
||||||
|
flags = 0
|
||||||
|
data = length 880, hash 8BFDE683
|
||||||
|
sample 26:
|
||||||
|
time = 433766
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 27:
|
||||||
|
time = 450450
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash 16B70503
|
||||||
|
sample 28:
|
||||||
|
time = 467133
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 29:
|
||||||
|
time = 483816
|
||||||
|
flags = 0
|
||||||
|
data = length 402, hash 51B5FAC9
|
||||||
|
sample 30:
|
||||||
|
time = 500500
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 31:
|
||||||
|
time = 517183
|
||||||
|
flags = 0
|
||||||
|
data = length 199, hash 12005069
|
||||||
|
sample 32:
|
||||||
|
time = 533866
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 33:
|
||||||
|
time = 550550
|
||||||
|
flags = 0
|
||||||
|
data = length 32362, hash F9FE31F7
|
||||||
|
sample 34:
|
||||||
|
time = 567233
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 35:
|
||||||
|
time = 583916
|
||||||
|
flags = 0
|
||||||
|
data = length 215, hash 2D4E3DC4
|
||||||
|
sample 36:
|
||||||
|
time = 600600
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 37:
|
||||||
|
time = 617283
|
||||||
|
flags = 0
|
||||||
|
data = length 450, hash C1A95E3
|
||||||
|
sample 38:
|
||||||
|
time = 633966
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 39:
|
||||||
|
time = 650650
|
||||||
|
flags = 0
|
||||||
|
data = length 221, hash 964386D9
|
||||||
|
sample 40:
|
||||||
|
time = 667333
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 41:
|
||||||
|
time = 684016
|
||||||
|
flags = 0
|
||||||
|
data = length 853, hash 2B9E0AAF
|
||||||
|
sample 42:
|
||||||
|
time = 700700
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 43:
|
||||||
|
time = 717383
|
||||||
|
flags = 0
|
||||||
|
data = length 236, hash 7E84BBAE
|
||||||
|
sample 44:
|
||||||
|
time = 734066
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 45:
|
||||||
|
time = 750750
|
||||||
|
flags = 0
|
||||||
|
data = length 419, hash 619235F2
|
||||||
|
sample 46:
|
||||||
|
time = 767433
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 47:
|
||||||
|
time = 784116
|
||||||
|
flags = 0
|
||||||
|
data = length 194, hash D386F352
|
||||||
|
sample 48:
|
||||||
|
time = 800800
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5A0
|
||||||
|
sample 49:
|
||||||
|
time = 817483
|
||||||
|
flags = 0
|
||||||
|
data = length 38679, hash 17E63FCD
|
||||||
|
sample 50:
|
||||||
|
time = 834166
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 51:
|
||||||
|
time = 850850
|
||||||
|
flags = 0
|
||||||
|
data = length 183, hash C8DD98E2
|
||||||
|
sample 52:
|
||||||
|
time = 867533
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 53:
|
||||||
|
time = 884216
|
||||||
|
flags = 0
|
||||||
|
data = length 457, hash 2B4E3476
|
||||||
|
sample 54:
|
||||||
|
time = 900900
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 55:
|
||||||
|
time = 917583
|
||||||
|
flags = 0
|
||||||
|
data = length 216, hash 7233540A
|
||||||
|
sample 56:
|
||||||
|
time = 934266
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 57:
|
||||||
|
time = 950950
|
||||||
|
flags = 0
|
||||||
|
data = length 894, hash 7319F313
|
||||||
|
sample 58:
|
||||||
|
time = 967633
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 59:
|
||||||
|
time = 984316
|
||||||
|
flags = 536870912
|
||||||
|
data = length 233, hash DE4DBE67
|
||||||
|
track 1:
|
||||||
|
total output bytes = 374
|
||||||
|
sample count = 1
|
||||||
|
format 0:
|
||||||
|
id = 2
|
||||||
|
sampleMimeType = audio/mp4a-latm
|
||||||
|
codecs = mp4a.40.2
|
||||||
|
maxInputSize = 441
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 44100
|
||||||
|
language = und
|
||||||
|
metadata = entries=[TSSE: description=null: value=Lavf58.76.100]
|
||||||
|
initializationData:
|
||||||
|
data = length 16, hash CAA21BBF
|
||||||
|
sample 0:
|
||||||
|
time = 998458
|
||||||
|
flags = 536870913
|
||||||
|
data = length 374, hash 6102A531
|
||||||
|
tracksEnded = true
|
454
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.unknown_length.dump
vendored
Normal file
454
testdata/src/test/assets/extractordumps/mp4/sample_with_colr_mdcv_and_clli.mp4.unknown_length.dump
vendored
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
seekMap:
|
||||||
|
isSeekable = true
|
||||||
|
duration = 1022000
|
||||||
|
getPosition(0) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(511000) = [[timeUs=0, position=48]]
|
||||||
|
getPosition(1022000) = [[timeUs=0, position=48]]
|
||||||
|
numberOfTracks = 2
|
||||||
|
track 0:
|
||||||
|
total output bytes = 266091
|
||||||
|
sample count = 60
|
||||||
|
format 0:
|
||||||
|
id = 1
|
||||||
|
sampleMimeType = video/av01
|
||||||
|
maxInputSize = 144656
|
||||||
|
width = 1920
|
||||||
|
height = 1080
|
||||||
|
frameRate = 59.940056
|
||||||
|
colorInfo:
|
||||||
|
colorSpace = 6
|
||||||
|
colorRange = 2
|
||||||
|
colorTransfer = 6
|
||||||
|
hdrStaticInfo = length 25, hash 423AFC35
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1
|
||||||
|
data = length 144626, hash 7C021D5F
|
||||||
|
sample 1:
|
||||||
|
time = 16683
|
||||||
|
flags = 0
|
||||||
|
data = length 4018, hash FA5E79FA
|
||||||
|
sample 2:
|
||||||
|
time = 33366
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 3:
|
||||||
|
time = 50050
|
||||||
|
flags = 0
|
||||||
|
data = length 144, hash 4A868A2F
|
||||||
|
sample 4:
|
||||||
|
time = 66733
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 5:
|
||||||
|
time = 83416
|
||||||
|
flags = 0
|
||||||
|
data = length 342, hash 5A2E1C3C
|
||||||
|
sample 6:
|
||||||
|
time = 100100
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 7:
|
||||||
|
time = 116783
|
||||||
|
flags = 0
|
||||||
|
data = length 173, hash CFE014B3
|
||||||
|
sample 8:
|
||||||
|
time = 133466
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 9:
|
||||||
|
time = 150150
|
||||||
|
flags = 0
|
||||||
|
data = length 655, hash 3A7738B6
|
||||||
|
sample 10:
|
||||||
|
time = 166833
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 11:
|
||||||
|
time = 183516
|
||||||
|
flags = 0
|
||||||
|
data = length 208, hash E7D2035A
|
||||||
|
sample 12:
|
||||||
|
time = 200200
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 13:
|
||||||
|
time = 216883
|
||||||
|
flags = 0
|
||||||
|
data = length 385, hash 4D025B28
|
||||||
|
sample 14:
|
||||||
|
time = 233566
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 15:
|
||||||
|
time = 250250
|
||||||
|
flags = 0
|
||||||
|
data = length 192, hash CC0BD164
|
||||||
|
sample 16:
|
||||||
|
time = 266933
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5B0
|
||||||
|
sample 17:
|
||||||
|
time = 283616
|
||||||
|
flags = 0
|
||||||
|
data = length 36989, hash C213D35E
|
||||||
|
sample 18:
|
||||||
|
time = 300300
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 19:
|
||||||
|
time = 316983
|
||||||
|
flags = 0
|
||||||
|
data = length 213, hash 2BBA39D3
|
||||||
|
sample 20:
|
||||||
|
time = 333666
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 21:
|
||||||
|
time = 350350
|
||||||
|
flags = 0
|
||||||
|
data = length 474, hash 83D66E3F
|
||||||
|
sample 22:
|
||||||
|
time = 367033
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 23:
|
||||||
|
time = 383716
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash CF512AF0
|
||||||
|
sample 24:
|
||||||
|
time = 400400
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 25:
|
||||||
|
time = 417083
|
||||||
|
flags = 0
|
||||||
|
data = length 880, hash 8BFDE683
|
||||||
|
sample 26:
|
||||||
|
time = 433766
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 27:
|
||||||
|
time = 450450
|
||||||
|
flags = 0
|
||||||
|
data = length 246, hash 16B70503
|
||||||
|
sample 28:
|
||||||
|
time = 467133
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 29:
|
||||||
|
time = 483816
|
||||||
|
flags = 0
|
||||||
|
data = length 402, hash 51B5FAC9
|
||||||
|
sample 30:
|
||||||
|
time = 500500
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 31:
|
||||||
|
time = 517183
|
||||||
|
flags = 0
|
||||||
|
data = length 199, hash 12005069
|
||||||
|
sample 32:
|
||||||
|
time = 533866
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5D0
|
||||||
|
sample 33:
|
||||||
|
time = 550550
|
||||||
|
flags = 0
|
||||||
|
data = length 32362, hash F9FE31F7
|
||||||
|
sample 34:
|
||||||
|
time = 567233
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 35:
|
||||||
|
time = 583916
|
||||||
|
flags = 0
|
||||||
|
data = length 215, hash 2D4E3DC4
|
||||||
|
sample 36:
|
||||||
|
time = 600600
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 37:
|
||||||
|
time = 617283
|
||||||
|
flags = 0
|
||||||
|
data = length 450, hash C1A95E3
|
||||||
|
sample 38:
|
||||||
|
time = 633966
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 39:
|
||||||
|
time = 650650
|
||||||
|
flags = 0
|
||||||
|
data = length 221, hash 964386D9
|
||||||
|
sample 40:
|
||||||
|
time = 667333
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 41:
|
||||||
|
time = 684016
|
||||||
|
flags = 0
|
||||||
|
data = length 853, hash 2B9E0AAF
|
||||||
|
sample 42:
|
||||||
|
time = 700700
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5E0
|
||||||
|
sample 43:
|
||||||
|
time = 717383
|
||||||
|
flags = 0
|
||||||
|
data = length 236, hash 7E84BBAE
|
||||||
|
sample 44:
|
||||||
|
time = 734066
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 45:
|
||||||
|
time = 750750
|
||||||
|
flags = 0
|
||||||
|
data = length 419, hash 619235F2
|
||||||
|
sample 46:
|
||||||
|
time = 767433
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 47:
|
||||||
|
time = 784116
|
||||||
|
flags = 0
|
||||||
|
data = length 194, hash D386F352
|
||||||
|
sample 48:
|
||||||
|
time = 800800
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5A0
|
||||||
|
sample 49:
|
||||||
|
time = 817483
|
||||||
|
flags = 0
|
||||||
|
data = length 38679, hash 17E63FCD
|
||||||
|
sample 50:
|
||||||
|
time = 834166
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 51:
|
||||||
|
time = 850850
|
||||||
|
flags = 0
|
||||||
|
data = length 183, hash C8DD98E2
|
||||||
|
sample 52:
|
||||||
|
time = 867533
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D600
|
||||||
|
sample 53:
|
||||||
|
time = 884216
|
||||||
|
flags = 0
|
||||||
|
data = length 457, hash 2B4E3476
|
||||||
|
sample 54:
|
||||||
|
time = 900900
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5F0
|
||||||
|
sample 55:
|
||||||
|
time = 917583
|
||||||
|
flags = 0
|
||||||
|
data = length 216, hash 7233540A
|
||||||
|
sample 56:
|
||||||
|
time = 934266
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D5C0
|
||||||
|
sample 57:
|
||||||
|
time = 950950
|
||||||
|
flags = 0
|
||||||
|
data = length 894, hash 7319F313
|
||||||
|
sample 58:
|
||||||
|
time = 967633
|
||||||
|
flags = 0
|
||||||
|
data = length 3, hash D610
|
||||||
|
sample 59:
|
||||||
|
time = 984316
|
||||||
|
flags = 536870912
|
||||||
|
data = length 233, hash DE4DBE67
|
||||||
|
track 1:
|
||||||
|
total output bytes = 16638
|
||||||
|
sample count = 44
|
||||||
|
format 0:
|
||||||
|
id = 2
|
||||||
|
sampleMimeType = audio/mp4a-latm
|
||||||
|
codecs = mp4a.40.2
|
||||||
|
maxInputSize = 441
|
||||||
|
channelCount = 2
|
||||||
|
sampleRate = 44100
|
||||||
|
language = und
|
||||||
|
metadata = entries=[TSSE: description=null: value=Lavf58.76.100]
|
||||||
|
initializationData:
|
||||||
|
data = length 16, hash CAA21BBF
|
||||||
|
sample 0:
|
||||||
|
time = 0
|
||||||
|
flags = 1
|
||||||
|
data = length 393, hash 706D1B6F
|
||||||
|
sample 1:
|
||||||
|
time = 23219
|
||||||
|
flags = 1
|
||||||
|
data = length 400, hash B48107D1
|
||||||
|
sample 2:
|
||||||
|
time = 46439
|
||||||
|
flags = 1
|
||||||
|
data = length 398, hash E5F4E9C1
|
||||||
|
sample 3:
|
||||||
|
time = 69659
|
||||||
|
flags = 1
|
||||||
|
data = length 400, hash 4317B40D
|
||||||
|
sample 4:
|
||||||
|
time = 92879
|
||||||
|
flags = 1
|
||||||
|
data = length 403, hash CB949D88
|
||||||
|
sample 5:
|
||||||
|
time = 116099
|
||||||
|
flags = 1
|
||||||
|
data = length 411, hash 616C8F82
|
||||||
|
sample 6:
|
||||||
|
time = 139319
|
||||||
|
flags = 1
|
||||||
|
data = length 392, hash 3BA50F06
|
||||||
|
sample 7:
|
||||||
|
time = 162539
|
||||||
|
flags = 1
|
||||||
|
data = length 401, hash 1C62F82C
|
||||||
|
sample 8:
|
||||||
|
time = 185759
|
||||||
|
flags = 1
|
||||||
|
data = length 400, hash 180FEA17
|
||||||
|
sample 9:
|
||||||
|
time = 208979
|
||||||
|
flags = 1
|
||||||
|
data = length 378, hash 2F6B0AE6
|
||||||
|
sample 10:
|
||||||
|
time = 232199
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash 6AE86D08
|
||||||
|
sample 11:
|
||||||
|
time = 255419
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash EF2FD9CC
|
||||||
|
sample 12:
|
||||||
|
time = 278639
|
||||||
|
flags = 1
|
||||||
|
data = length 374, hash 97B83243
|
||||||
|
sample 13:
|
||||||
|
time = 301859
|
||||||
|
flags = 1
|
||||||
|
data = length 382, hash 8BD6191C
|
||||||
|
sample 14:
|
||||||
|
time = 325079
|
||||||
|
flags = 1
|
||||||
|
data = length 393, hash D5F53221
|
||||||
|
sample 15:
|
||||||
|
time = 348299
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash 2437C16B
|
||||||
|
sample 16:
|
||||||
|
time = 371519
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash EE50108B
|
||||||
|
sample 17:
|
||||||
|
time = 394739
|
||||||
|
flags = 1
|
||||||
|
data = length 364, hash 9952E0FE
|
||||||
|
sample 18:
|
||||||
|
time = 417959
|
||||||
|
flags = 1
|
||||||
|
data = length 387, hash C4EC0E45
|
||||||
|
sample 19:
|
||||||
|
time = 441179
|
||||||
|
flags = 1
|
||||||
|
data = length 384, hash 7DFB424F
|
||||||
|
sample 20:
|
||||||
|
time = 464399
|
||||||
|
flags = 1
|
||||||
|
data = length 370, hash 28619E43
|
||||||
|
sample 21:
|
||||||
|
time = 487619
|
||||||
|
flags = 1
|
||||||
|
data = length 373, hash 440EB9E8
|
||||||
|
sample 22:
|
||||||
|
time = 510839
|
||||||
|
flags = 1
|
||||||
|
data = length 363, hash B7655913
|
||||||
|
sample 23:
|
||||||
|
time = 534058
|
||||||
|
flags = 1
|
||||||
|
data = length 362, hash A0690E92
|
||||||
|
sample 24:
|
||||||
|
time = 557278
|
||||||
|
flags = 1
|
||||||
|
data = length 377, hash 41BF1244
|
||||||
|
sample 25:
|
||||||
|
time = 580498
|
||||||
|
flags = 1
|
||||||
|
data = length 371, hash EE4124CD
|
||||||
|
sample 26:
|
||||||
|
time = 603718
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash 7A512168
|
||||||
|
sample 27:
|
||||||
|
time = 626938
|
||||||
|
flags = 1
|
||||||
|
data = length 370, hash ED00D55C
|
||||||
|
sample 28:
|
||||||
|
time = 650158
|
||||||
|
flags = 1
|
||||||
|
data = length 356, hash 43F4FFCA
|
||||||
|
sample 29:
|
||||||
|
time = 673378
|
||||||
|
flags = 1
|
||||||
|
data = length 373, hash 1950F38C
|
||||||
|
sample 30:
|
||||||
|
time = 696598
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 5F426A7A
|
||||||
|
sample 31:
|
||||||
|
time = 719818
|
||||||
|
flags = 1
|
||||||
|
data = length 371, hash FCC286D2
|
||||||
|
sample 32:
|
||||||
|
time = 743038
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash CF6F5DD9
|
||||||
|
sample 33:
|
||||||
|
time = 766258
|
||||||
|
flags = 1
|
||||||
|
data = length 386, hash 83E3B1E6
|
||||||
|
sample 34:
|
||||||
|
time = 789478
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash 5BDF670B
|
||||||
|
sample 35:
|
||||||
|
time = 812698
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash DC847E4D
|
||||||
|
sample 36:
|
||||||
|
time = 835918
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash 8AC0C55C
|
||||||
|
sample 37:
|
||||||
|
time = 859138
|
||||||
|
flags = 1
|
||||||
|
data = length 375, hash C0D4BF4
|
||||||
|
sample 38:
|
||||||
|
time = 882358
|
||||||
|
flags = 1
|
||||||
|
data = length 367, hash 6C5284E2
|
||||||
|
sample 39:
|
||||||
|
time = 905578
|
||||||
|
flags = 1
|
||||||
|
data = length 380, hash BDFAB187
|
||||||
|
sample 40:
|
||||||
|
time = 928798
|
||||||
|
flags = 1
|
||||||
|
data = length 372, hash CEF87EB6
|
||||||
|
sample 41:
|
||||||
|
time = 952018
|
||||||
|
flags = 1
|
||||||
|
data = length 369, hash B0FF049B
|
||||||
|
sample 42:
|
||||||
|
time = 975238
|
||||||
|
flags = 1
|
||||||
|
data = length 366, hash BADD46E6
|
||||||
|
sample 43:
|
||||||
|
time = 998458
|
||||||
|
flags = 536870913
|
||||||
|
data = length 374, hash 6102A531
|
||||||
|
tracksEnded = true
|
BIN
testdata/src/test/assets/media/mp4/sample_with_colr_mdcv_and_clli.mp4
vendored
Normal file
BIN
testdata/src/test/assets/media/mp4/sample_with_colr_mdcv_and_clli.mp4
vendored
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user