use of com.google.android.exoplayer2.ext.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State in project ExoPlayer by google.
the class DvbParser method decode.
/**
* Decodes a subtitling packet, returning a list of parsed {@link Cue}s.
*
* @param data The subtitling packet data to decode.
* @param limit The limit in {@code data} at which to stop decoding.
* @return The parsed {@link Cue}s.
*/
public List<Cue> decode(byte[] data, int limit) {
// Parse the input data.
ParsableBitArray dataBitArray = new ParsableBitArray(data, limit);
while (// sync_byte (8) + segment header (40)
dataBitArray.bitsLeft() >= 48 && dataBitArray.readBits(8) == 0x0F) {
parseSubtitlingSegment(dataBitArray, subtitleService);
}
@Nullable PageComposition pageComposition = subtitleService.pageComposition;
if (pageComposition == null) {
return Collections.emptyList();
}
// Update the canvas bitmap if necessary.
DisplayDefinition displayDefinition = subtitleService.displayDefinition != null ? subtitleService.displayDefinition : defaultDisplayDefinition;
if (bitmap == null || displayDefinition.width + 1 != bitmap.getWidth() || displayDefinition.height + 1 != bitmap.getHeight()) {
bitmap = Bitmap.createBitmap(displayDefinition.width + 1, displayDefinition.height + 1, Bitmap.Config.ARGB_8888);
canvas.setBitmap(bitmap);
}
// Build the cues.
List<Cue> cues = new ArrayList<>();
SparseArray<PageRegion> pageRegions = pageComposition.regions;
for (int i = 0; i < pageRegions.size(); i++) {
// Save clean clipping state.
canvas.save();
PageRegion pageRegion = pageRegions.valueAt(i);
int regionId = pageRegions.keyAt(i);
RegionComposition regionComposition = subtitleService.regions.get(regionId);
// Clip drawing to the current region and display definition window.
int baseHorizontalAddress = pageRegion.horizontalAddress + displayDefinition.horizontalPositionMinimum;
int baseVerticalAddress = pageRegion.verticalAddress + displayDefinition.verticalPositionMinimum;
int clipRight = min(baseHorizontalAddress + regionComposition.width, displayDefinition.horizontalPositionMaximum);
int clipBottom = min(baseVerticalAddress + regionComposition.height, displayDefinition.verticalPositionMaximum);
canvas.clipRect(baseHorizontalAddress, baseVerticalAddress, clipRight, clipBottom);
ClutDefinition clutDefinition = subtitleService.cluts.get(regionComposition.clutId);
if (clutDefinition == null) {
clutDefinition = subtitleService.ancillaryCluts.get(regionComposition.clutId);
if (clutDefinition == null) {
clutDefinition = defaultClutDefinition;
}
}
SparseArray<RegionObject> regionObjects = regionComposition.regionObjects;
for (int j = 0; j < regionObjects.size(); j++) {
int objectId = regionObjects.keyAt(j);
RegionObject regionObject = regionObjects.valueAt(j);
ObjectData objectData = subtitleService.objects.get(objectId);
if (objectData == null) {
objectData = subtitleService.ancillaryObjects.get(objectId);
}
if (objectData != null) {
@Nullable Paint paint = objectData.nonModifyingColorFlag ? null : defaultPaint;
paintPixelDataSubBlocks(objectData, clutDefinition, regionComposition.depth, baseHorizontalAddress + regionObject.horizontalPosition, baseVerticalAddress + regionObject.verticalPosition, paint, canvas);
}
}
if (regionComposition.fillFlag) {
int color;
if (regionComposition.depth == REGION_DEPTH_8_BIT) {
color = clutDefinition.clutEntries8Bit[regionComposition.pixelCode8Bit];
} else if (regionComposition.depth == REGION_DEPTH_4_BIT) {
color = clutDefinition.clutEntries4Bit[regionComposition.pixelCode4Bit];
} else {
color = clutDefinition.clutEntries2Bit[regionComposition.pixelCode2Bit];
}
fillRegionPaint.setColor(color);
canvas.drawRect(baseHorizontalAddress, baseVerticalAddress, baseHorizontalAddress + regionComposition.width, baseVerticalAddress + regionComposition.height, fillRegionPaint);
}
cues.add(new Cue.Builder().setBitmap(Bitmap.createBitmap(bitmap, baseHorizontalAddress, baseVerticalAddress, regionComposition.width, regionComposition.height)).setPosition((float) baseHorizontalAddress / displayDefinition.width).setPositionAnchor(Cue.ANCHOR_TYPE_START).setLine((float) baseVerticalAddress / displayDefinition.height, Cue.LINE_TYPE_FRACTION).setLineAnchor(Cue.ANCHOR_TYPE_START).setSize((float) regionComposition.width / displayDefinition.width).setBitmapHeight((float) regionComposition.height / displayDefinition.height).build());
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
// Restore clean clipping state.
canvas.restore();
}
return Collections.unmodifiableList(cues);
}
use of com.google.android.exoplayer2.ext.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State in project ExoPlayer by google.
the class HlsChunkSource method getChunkPublicationState.
/**
* Returns the publication state of the given chunk.
*
* @param mediaChunk The media chunk for which to evaluate the publication state.
* @return Whether the media chunk is {@link #CHUNK_PUBLICATION_STATE_PRELOAD a preload chunk},
* has been {@link #CHUNK_PUBLICATION_STATE_REMOVED removed} or is definitely {@link
* #CHUNK_PUBLICATION_STATE_PUBLISHED published}.
*/
@ChunkPublicationState
public int getChunkPublicationState(HlsMediaChunk mediaChunk) {
if (mediaChunk.partIndex == C.INDEX_UNSET) {
// Chunks based on full segments can't be removed and are always published.
return CHUNK_PUBLICATION_STATE_PUBLISHED;
}
Uri playlistUrl = playlistUrls[trackGroup.indexOf(mediaChunk.trackFormat)];
HlsMediaPlaylist mediaPlaylist = checkNotNull(playlistTracker.getPlaylistSnapshot(playlistUrl, /* isForPlayback= */
false));
int segmentIndexInPlaylist = (int) (mediaChunk.chunkIndex - mediaPlaylist.mediaSequence);
if (segmentIndexInPlaylist < 0) {
// The parent segment of the previous chunk is not in the current playlist anymore.
return CHUNK_PUBLICATION_STATE_PUBLISHED;
}
List<HlsMediaPlaylist.Part> partsInCurrentPlaylist = segmentIndexInPlaylist < mediaPlaylist.segments.size() ? mediaPlaylist.segments.get(segmentIndexInPlaylist).parts : mediaPlaylist.trailingParts;
if (mediaChunk.partIndex >= partsInCurrentPlaylist.size()) {
// sequence in the new playlist.
return CHUNK_PUBLICATION_STATE_REMOVED;
}
HlsMediaPlaylist.Part newPart = partsInCurrentPlaylist.get(mediaChunk.partIndex);
if (newPart.isPreload) {
// The playlist did not change and the part in the new playlist is still a preload hint.
return CHUNK_PUBLICATION_STATE_PRELOAD;
}
Uri newUri = Uri.parse(UriUtil.resolve(mediaPlaylist.baseUri, newPart.url));
return Util.areEqual(newUri, mediaChunk.dataSpec.uri) ? CHUNK_PUBLICATION_STATE_PUBLISHED : CHUNK_PUBLICATION_STATE_REMOVED;
}
use of com.google.android.exoplayer2.ext.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State in project ExoPlayer by google.
the class DefaultDrmSessionManager method acquireSession.
// DrmSessionManager implementation.
@Override
public DrmSession<T> acquireSession(Looper playbackLooper, DrmInitData drmInitData) {
Assertions.checkState(this.playbackLooper == null || this.playbackLooper == playbackLooper);
if (++openCount != 1) {
return this;
}
if (this.playbackLooper == null) {
this.playbackLooper = playbackLooper;
mediaDrmHandler = new MediaDrmHandler(playbackLooper);
postResponseHandler = new PostResponseHandler(playbackLooper);
}
requestHandlerThread = new HandlerThread("DrmRequestHandler");
requestHandlerThread.start();
postRequestHandler = new PostRequestHandler(requestHandlerThread.getLooper());
if (offlineLicenseKeySetId == null) {
SchemeData schemeData = drmInitData.get(uuid);
if (schemeData == null) {
onError(new IllegalStateException("Media does not support uuid: " + uuid));
return this;
}
schemeInitData = schemeData.data;
schemeMimeType = schemeData.mimeType;
if (Util.SDK_INT < 21) {
// Prior to L the Widevine CDM required data to be extracted from the PSSH atom.
byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeInitData, C.WIDEVINE_UUID);
if (psshData == null) {
// Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged.
} else {
schemeInitData = psshData;
}
}
if (Util.SDK_INT < 26 && C.CLEARKEY_UUID.equals(uuid) && (MimeTypes.VIDEO_MP4.equals(schemeMimeType) || MimeTypes.AUDIO_MP4.equals(schemeMimeType))) {
// Prior to API level 26 the ClearKey CDM only accepted "cenc" as the scheme for MP4.
schemeMimeType = CENC_SCHEME_MIME_TYPE;
}
}
state = STATE_OPENING;
openInternal(true);
return this;
}
use of com.google.android.exoplayer2.ext.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State in project ExoPlayer by google.
the class HlsMediaPeriod method selectTracks.
@Override
public long selectTracks(TrackSelection[] selections, boolean[] mayRetainStreamFlags, SampleStream[] streams, boolean[] streamResetFlags, long positionUs) {
// Map each selection and stream onto a child period index.
int[] streamChildIndices = new int[selections.length];
int[] selectionChildIndices = new int[selections.length];
for (int i = 0; i < selections.length; i++) {
streamChildIndices[i] = streams[i] == null ? C.INDEX_UNSET : streamWrapperIndices.get(streams[i]);
selectionChildIndices[i] = C.INDEX_UNSET;
if (selections[i] != null) {
TrackGroup trackGroup = selections[i].getTrackGroup();
for (int j = 0; j < sampleStreamWrappers.length; j++) {
if (sampleStreamWrappers[j].getTrackGroups().indexOf(trackGroup) != C.INDEX_UNSET) {
selectionChildIndices[i] = j;
break;
}
}
}
}
boolean selectedNewTracks = false;
streamWrapperIndices.clear();
// Select tracks for each child, copying the resulting streams back into a new streams array.
SampleStream[] newStreams = new SampleStream[selections.length];
SampleStream[] childStreams = new SampleStream[selections.length];
TrackSelection[] childSelections = new TrackSelection[selections.length];
ArrayList<HlsSampleStreamWrapper> enabledSampleStreamWrapperList = new ArrayList<>(sampleStreamWrappers.length);
for (int i = 0; i < sampleStreamWrappers.length; i++) {
for (int j = 0; j < selections.length; j++) {
childStreams[j] = streamChildIndices[j] == i ? streams[j] : null;
childSelections[j] = selectionChildIndices[j] == i ? selections[j] : null;
}
selectedNewTracks |= sampleStreamWrappers[i].selectTracks(childSelections, mayRetainStreamFlags, childStreams, streamResetFlags, !seenFirstTrackSelection);
boolean wrapperEnabled = false;
for (int j = 0; j < selections.length; j++) {
if (selectionChildIndices[j] == i) {
// Assert that the child provided a stream for the selection.
Assertions.checkState(childStreams[j] != null);
newStreams[j] = childStreams[j];
wrapperEnabled = true;
streamWrapperIndices.put(childStreams[j], i);
} else if (streamChildIndices[j] == i) {
// Assert that the child cleared any previous stream.
Assertions.checkState(childStreams[j] == null);
}
}
if (wrapperEnabled) {
enabledSampleStreamWrapperList.add(sampleStreamWrappers[i]);
}
}
// Copy the new streams back into the streams array.
System.arraycopy(newStreams, 0, streams, 0, newStreams.length);
// Update the local state.
enabledSampleStreamWrappers = new HlsSampleStreamWrapper[enabledSampleStreamWrapperList.size()];
enabledSampleStreamWrapperList.toArray(enabledSampleStreamWrappers);
// initialization.
if (enabledSampleStreamWrappers.length > 0) {
enabledSampleStreamWrappers[0].setIsTimestampMaster(true);
for (int i = 1; i < enabledSampleStreamWrappers.length; i++) {
enabledSampleStreamWrappers[i].setIsTimestampMaster(false);
}
}
sequenceableLoader = new CompositeSequenceableLoader(enabledSampleStreamWrappers);
if (seenFirstTrackSelection && selectedNewTracks) {
seekToUs(positionUs);
// We'll need to reset renderers consuming from all streams due to the seek.
for (int i = 0; i < selections.length; i++) {
if (streams[i] != null) {
streamResetFlags[i] = true;
}
}
}
seenFirstTrackSelection = true;
return positionUs;
}
use of com.google.android.exoplayer2.ext.ima.ImaServerSideAdInsertionMediaSource.AdsLoader.State in project ExoPlayer by google.
the class WebvttDecoder method decode.
@Override
protected WebvttSubtitle decode(byte[] bytes, int length) throws SubtitleDecoderException {
parsableWebvttData.reset(bytes, length);
// Initialization for consistent starting state.
webvttCueBuilder.reset();
definedStyles.clear();
// Validate the first line of the header, and skip the remainder.
WebvttParserUtil.validateWebvttHeaderLine(parsableWebvttData);
while (!TextUtils.isEmpty(parsableWebvttData.readLine())) {
}
int event;
ArrayList<WebvttCue> subtitles = new ArrayList<>();
while ((event = getNextEvent(parsableWebvttData)) != EVENT_END_OF_FILE) {
if (event == EVENT_COMMENT) {
skipComment(parsableWebvttData);
} else if (event == EVENT_STYLE_BLOCK) {
if (!subtitles.isEmpty()) {
throw new SubtitleDecoderException("A style block was found after the first cue.");
}
// Consume the "STYLE" header.
parsableWebvttData.readLine();
WebvttCssStyle styleBlock = cssParser.parseBlock(parsableWebvttData);
if (styleBlock != null) {
definedStyles.add(styleBlock);
}
} else if (event == EVENT_CUE) {
if (cueParser.parseCue(parsableWebvttData, webvttCueBuilder, definedStyles)) {
subtitles.add(webvttCueBuilder.build());
webvttCueBuilder.reset();
}
}
}
return new WebvttSubtitle(subtitles);
}
Aggregations