use of androidx.annotation.Nullable in project ExoPlayer by google.
the class MediaCodecUtil method getAvcProfileAndLevel.
@Nullable
private static Pair<Integer, Integer> getAvcProfileAndLevel(String codec, String[] parts) {
if (parts.length < 2) {
// The codec has fewer parts than required by the AVC codec string format.
Log.w(TAG, "Ignoring malformed AVC codec string: " + codec);
return null;
}
int profileInteger;
int levelInteger;
try {
if (parts[1].length() == 6) {
// Format: avc1.xxccyy, where xx is profile and yy level, both hexadecimal.
profileInteger = Integer.parseInt(parts[1].substring(0, 2), 16);
levelInteger = Integer.parseInt(parts[1].substring(4), 16);
} else if (parts.length >= 3) {
// Format: avc1.xx.[y]yy where xx is profile and [y]yy level, both decimal.
profileInteger = Integer.parseInt(parts[1]);
levelInteger = Integer.parseInt(parts[2]);
} else {
// We don't recognize the format.
Log.w(TAG, "Ignoring malformed AVC codec string: " + codec);
return null;
}
} catch (NumberFormatException e) {
Log.w(TAG, "Ignoring malformed AVC codec string: " + codec);
return null;
}
int profile = avcProfileNumberToConst(profileInteger);
if (profile == -1) {
Log.w(TAG, "Unknown AVC profile: " + profileInteger);
return null;
}
int level = avcLevelNumberToConst(levelInteger);
if (level == -1) {
Log.w(TAG, "Unknown AVC level: " + levelInteger);
return null;
}
return new Pair<>(profile, level);
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class BatchBuffer method append.
/**
* Attempts to append the provided buffer.
*
* @param buffer The buffer to try and append.
* @return Whether the buffer was successfully appended.
* @throws IllegalArgumentException If the {@code buffer} is encrypted, has supplemental data, or
* is an end of stream buffer, none of which are supported.
*/
public boolean append(DecoderInputBuffer buffer) {
checkArgument(!buffer.isEncrypted());
checkArgument(!buffer.hasSupplementalData());
checkArgument(!buffer.isEndOfStream());
if (!canAppendSampleBuffer(buffer)) {
return false;
}
if (sampleCount++ == 0) {
timeUs = buffer.timeUs;
if (buffer.isKeyFrame()) {
setFlags(C.BUFFER_FLAG_KEY_FRAME);
}
}
if (buffer.isDecodeOnly()) {
setFlags(C.BUFFER_FLAG_DECODE_ONLY);
}
@Nullable ByteBuffer bufferData = buffer.data;
if (bufferData != null) {
ensureSpaceForWrite(bufferData.remaining());
data.put(bufferData);
}
lastSampleTimeUs = buffer.timeUs;
return true;
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class DownloadService method onStartCommand.
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
lastStartId = startId;
taskRemoved = false;
@Nullable String intentAction = null;
@Nullable String contentId = null;
if (intent != null) {
intentAction = intent.getAction();
contentId = intent.getStringExtra(KEY_CONTENT_ID);
startedInForeground |= intent.getBooleanExtra(KEY_FOREGROUND, false) || ACTION_RESTART.equals(intentAction);
}
// intentAction is null if the service is restarted or no action is specified.
if (intentAction == null) {
intentAction = ACTION_INIT;
}
DownloadManager downloadManager = Assertions.checkNotNull(downloadManagerHelper).downloadManager;
switch(intentAction) {
case ACTION_INIT:
case ACTION_RESTART:
// Do nothing.
break;
case ACTION_ADD_DOWNLOAD:
@Nullable DownloadRequest downloadRequest = Assertions.checkNotNull(intent).getParcelableExtra(KEY_DOWNLOAD_REQUEST);
if (downloadRequest == null) {
Log.e(TAG, "Ignored ADD_DOWNLOAD: Missing " + KEY_DOWNLOAD_REQUEST + " extra");
} else {
int stopReason = intent.getIntExtra(KEY_STOP_REASON, Download.STOP_REASON_NONE);
downloadManager.addDownload(downloadRequest, stopReason);
}
break;
case ACTION_REMOVE_DOWNLOAD:
if (contentId == null) {
Log.e(TAG, "Ignored REMOVE_DOWNLOAD: Missing " + KEY_CONTENT_ID + " extra");
} else {
downloadManager.removeDownload(contentId);
}
break;
case ACTION_REMOVE_ALL_DOWNLOADS:
downloadManager.removeAllDownloads();
break;
case ACTION_RESUME_DOWNLOADS:
downloadManager.resumeDownloads();
break;
case ACTION_PAUSE_DOWNLOADS:
downloadManager.pauseDownloads();
break;
case ACTION_SET_STOP_REASON:
if (!Assertions.checkNotNull(intent).hasExtra(KEY_STOP_REASON)) {
Log.e(TAG, "Ignored SET_STOP_REASON: Missing " + KEY_STOP_REASON + " extra");
} else {
int stopReason = intent.getIntExtra(KEY_STOP_REASON, /* defaultValue= */
0);
downloadManager.setStopReason(contentId, stopReason);
}
break;
case ACTION_SET_REQUIREMENTS:
@Nullable Requirements requirements = Assertions.checkNotNull(intent).getParcelableExtra(KEY_REQUIREMENTS);
if (requirements == null) {
Log.e(TAG, "Ignored SET_REQUIREMENTS: Missing " + KEY_REQUIREMENTS + " extra");
} else {
downloadManager.setRequirements(requirements);
}
break;
default:
Log.e(TAG, "Ignored unrecognized action: " + intentAction);
break;
}
if (Util.SDK_INT >= 26 && startedInForeground && foregroundNotificationUpdater != null) {
// From API level 26, services started in the foreground are required to show a notification.
foregroundNotificationUpdater.showNotificationIfNotAlready();
}
isStopped = false;
if (downloadManager.isIdle()) {
onIdle();
}
return START_STICKY;
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class SegmentDownloader method mergeSegments.
private static void mergeSegments(List<Segment> segments, CacheKeyFactory keyFactory) {
HashMap<String, Integer> lastIndexByCacheKey = new HashMap<>();
int nextOutIndex = 0;
for (int i = 0; i < segments.size(); i++) {
Segment segment = segments.get(i);
String cacheKey = keyFactory.buildCacheKey(segment.dataSpec);
@Nullable Integer lastIndex = lastIndexByCacheKey.get(cacheKey);
@Nullable Segment lastSegment = lastIndex == null ? null : segments.get(lastIndex);
if (lastSegment == null || segment.startTimeUs > lastSegment.startTimeUs + MAX_MERGED_SEGMENT_START_TIME_DIFF_US || !canMergeSegments(lastSegment.dataSpec, segment.dataSpec)) {
lastIndexByCacheKey.put(cacheKey, nextOutIndex);
segments.set(nextOutIndex, segment);
nextOutIndex++;
} else {
long mergedLength = segment.dataSpec.length == C.LENGTH_UNSET ? C.LENGTH_UNSET : lastSegment.dataSpec.length + segment.dataSpec.length;
DataSpec mergedDataSpec = lastSegment.dataSpec.subrange(/* offset= */
0, mergedLength);
segments.set(Assertions.checkNotNull(lastIndex), new Segment(lastSegment.startTimeUs, mergedDataSpec));
}
}
Util.removeRange(segments, /* fromIndex= */
nextOutIndex, /* toIndex= */
segments.size());
}
use of androidx.annotation.Nullable in project ExoPlayer by google.
the class Util method getCurrentDisplayModeSize.
/**
* Gets the size of the current mode of the specified display, in pixels.
*
* <p>Note that due to application UI scaling, the number of pixels made available to applications
* (as reported by {@link Display#getSize(Point)} may differ from the mode's actual resolution (as
* reported by this function). For example, applications running on a display configured with a 4K
* mode may have their UI laid out and rendered in 1080p and then scaled up. Applications can take
* advantage of the full mode resolution through a {@link SurfaceView} using full size buffers.
*
* @param context Any context.
* @param display The display whose size is to be returned.
* @return The size of the current mode, in pixels.
*/
public static Point getCurrentDisplayModeSize(Context context, Display display) {
if (display.getDisplayId() == Display.DEFAULT_DISPLAY && isTv(context)) {
// On Android TVs it's common for the UI to be driven at a lower resolution than the physical
// resolution of the display (e.g., driving the UI at 1080p when the display is 4K).
// SurfaceView outputs are still able to use the full physical resolution on such devices.
//
// Prior to API level 26, the Display object did not provide a way to obtain the true physical
// resolution of the display. From API level 26, Display.getMode().getPhysical[Width|Height]
// is expected to return the display's true physical resolution, but we still see devices
// setting their hardware compositor output size incorrectly, which makes this unreliable.
// Hence for TV devices, we try and read the display's true physical resolution from system
// properties.
//
// From API level 28, Treble may prevent the system from writing sys.display-size, so we check
// vendor.display-size instead.
@Nullable String displaySize = Util.SDK_INT < 28 ? getSystemProperty("sys.display-size") : getSystemProperty("vendor.display-size");
// If we managed to read the display size, attempt to parse it.
if (!TextUtils.isEmpty(displaySize)) {
try {
String[] displaySizeParts = split(displaySize.trim(), "x");
if (displaySizeParts.length == 2) {
int width = Integer.parseInt(displaySizeParts[0]);
int height = Integer.parseInt(displaySizeParts[1]);
if (width > 0 && height > 0) {
return new Point(width, height);
}
}
} catch (NumberFormatException e) {
// Do nothing.
}
Log.e(TAG, "Invalid display size: " + displaySize);
}
// Sony Android TVs advertise support for 4k output via a system feature.
if ("Sony".equals(Util.MANUFACTURER) && Util.MODEL.startsWith("BRAVIA") && context.getPackageManager().hasSystemFeature("com.sony.dtv.hardware.panel.qfhd")) {
return new Point(3840, 2160);
}
}
Point displaySize = new Point();
if (Util.SDK_INT >= 23) {
getDisplaySizeV23(display, displaySize);
} else if (Util.SDK_INT >= 17) {
getDisplaySizeV17(display, displaySize);
} else {
getDisplaySizeV16(display, displaySize);
}
return displaySize;
}
Aggregations