567 Commits

Author SHA1 Message Date
tonihei
b3788ce568 Remove deprecated stop(boolean)
This method has been deprecated for over 2 years.

PiperOrigin-RevId: 520586238
2023-03-30 17:24:35 +00:00
ibaker
f4a3478d84 Use Future.get() @Deterministic annotation in OfflineLicenseHelper
This means we don't need to manually store the result of `get()` into a
local to convince the nullness checker that it remains non-null.

PiperOrigin-RevId: 520576719
2023-03-30 17:23:55 +00:00
bachinger
f599a9b8f9 Keep content timeline and ad playback states together
For multi-period live streams the content timeline for
which the global ad playback state has been split needs
to be kept together to not run into a race between
timeline refreshes and ad events.

PiperOrigin-RevId: 520358964
2023-03-30 17:23:14 +00:00
tonihei
6952771e2f Remove remaining references to exoplayer.dev
PiperOrigin-RevId: 520314781
2023-03-30 17:20:36 +00:00
ibaker
376bddef47 Post OfflineLicenseHelper interactions to its internal handler thread
`DefaultDrmSession(Manager)` expect most of their methods to be called
on the 'playback thread'. There isn't a playback thread in the case of
`OfflineLicenseHelper`, but in that case it's the thread backing
`DefaultDrmSessionManager.playbackLooper`, which is `OfflineLicenseHelper.handlerThread`.

PiperOrigin-RevId: 520053006
2023-03-30 17:19:53 +00:00
Googler
f88280dc78 Allow associating LoadControl methods with the relevant MediaPeriod.
PiperOrigin-RevId: 520037412
2023-03-30 17:19:10 +00:00
tianyifeng
26aee812d5 Rollback of 6109a0eb62
*** Original commit ***

Intercept audio capabilities change in `DefaultAudioSink`

***

PiperOrigin-RevId: 519760267
2023-03-30 17:13:34 +00:00
ibaker
2c05a9af26 Use TestUtil.getPublicMethods instead of getDeclaredMethods
JaCoCo introduces private synthetic methods (even on interfaces) which
have to be skipped when checking that a 'forwarding' implementation does
forward everything. Instead we can use the existing `getPublicMethods()`
method which implicitly skips these (since they're private).

PiperOrigin-RevId: 519665752
2023-03-30 17:11:30 +00:00
tonihei
b9790e69d7 Handle output format changes for empty sample streams correctly
When MediaCodecRenderer is given an empty sample stream, it puts
its output format change tracking in a bad state where we never
process future stream changes because we are waiting for a sample
that doesn't exist.

We can fix this by:
 - Looping the pending output stream changes to see if we processed
   more than one change at once (this fixes the tracking for empty
   sample streams that are not the first in the queue).
 - Checking if none of the previous streams queued any samples in
   onStreamChanged to handle this in the same way as the case
   where we already output all samples (this fixes the problem when
   the empty sample stream comes first in the queue).
 - Also calling onProcessedStreamChange for the case above, which
   was missing previously.

#minor-release

PiperOrigin-RevId: 519226637
2023-03-30 17:10:49 +00:00
tonihei
fc54a7a487 Add COMMAND_RELEASE to set whether Player instances can be released
This wasn't added so far because releasing is always allowed from a
MediaController (as it just releases the connection, not the session
player). But Player instances can be created for other purposes and
the receiver of a Player instance should not always be allowed to
call release if it doesn't own the player resource.

PiperOrigin-RevId: 519121122
2023-03-30 17:09:28 +00:00
Tianyi Feng
dc3481fca7 Merge pull request #11051 from TiVo:p-fix-for-issue-11050
PiperOrigin-RevId: 518953648
2023-03-30 17:06:46 +00:00
bachinger
0bae410f7d Use final reference to content timeline inside handler message
The content timeline field may be updated when the live timeline
is refreshed in the looper event preceding the runnable that is
posted to the player thread. Hence a new timeline may contain a
new period uid that is not present in the ad playback state map.

Using a final reference makes sure period and ad playback state
match when asserted.

PiperOrigin-RevId: 518228165
2023-03-21 14:21:21 +00:00
bachinger
0a2a20d4fb Skip played live ad media periods
This change makes sure that live ad periods that are played are
skip when attempted to be added to the queue. To make this work
the existing filter logic had to be take into account the content
resume offset that live periods use.

PiperOrigin-RevId: 518068138
2023-03-21 14:20:43 +00:00
bachinger
b13b272695 Use correct period duration in fake live timeline
PiperOrigin-RevId: 517953981
2023-03-21 14:18:30 +00:00
tianyifeng
6109a0eb62 Intercept audio capabilities change in DefaultAudioSink
PiperOrigin-RevId: 517144710
2023-03-21 14:13:07 +00:00
tianyifeng
841c5477d1 Add release method to Renderer and AudioSink
* Add `release` method to Renderer and AudioSink interfaces.
* Call the `release` method for renderers when the ExoPlayer is going to be released.

PiperOrigin-RevId: 517135677
2023-03-21 14:12:21 +00:00
michaelkatz
ea6241cc04 Extrapolate playback position during audio offload sleep
While playback thread is 'asleep' during audio offload playback, the playbackInfo.positionUs is not being constantly updated. During this time, the returned value from getCurrentPosition should return an estimate based on the most recent value and playback speed.

PiperOrigin-RevId: 516550509
2023-03-16 15:30:12 +00:00
tianyifeng
796412b4be Detect audio device change from API 23 with AudioCapabilitiesReceiver
* Add AudioDeviceCallbackApi23 class which extends the AudioDeviceCallback.
* Add registerAudioDeviceCallback and unregisterAudioDeviceCallback methods for Api23.
* Modify the logics of AudioCapabilitiesReceiver constructor, register and unregister methods.

PiperOrigin-RevId: 516183997
2023-03-14 07:54:31 +00:00
christosts
7cf758f837 Log Format.colorInfo
Log Format.colorInfo in EventLogger and the demo app's debug text.

#minor-release

PiperOrigin-RevId: 516172936
2023-03-14 07:53:43 +00:00
bachinger
2dee3bf46c Ignore live SSAI postroll placeholders in MediaPeriodQueue
This change makes sure that the `AdPlaybackState` of any period can
contain an empty postroll placeholder.

The placeholder postroll should be represented in the `MediaPeriodId`
of a content period as `nextAdGroupIndex`, but should be ignored when
building the list of `MediaPeriodInfo` in the `MediaPeriodQueue`. This
is required to allow to add an ad group to ad playback state of the
content period that is currently being played, instantly insert an ad
period into the media period queue and immediately transition playback
to the new period.

This change makes sure and tests that

- a live server side inserted postroll placeholder can be inserted to
  a `AdPlaybackState` in well-defined and tested way (helper method)
- a postroll placeholder is NOT ignored when
  `AdPlaybackState.getAdGroupIndexAfterPositionUs` is called (this
   is required when evaluating the `nextAdGroupIndex`).
- a postroll placeholder is ignored when
  `AdPlaybackState.getAdGroupIndexForPositionUs` is called (this is
  required to not attempt to play the ad and is analogous to ignore the
  post roll placeholder in a single period timeline).
- `MediaPeriod.getFollowingMediaPeriodInfo()` does not include a
  `MediaPeriodInfo` for the placeholder postroll when building the
   queue.

PiperOrigin-RevId: 515079136
2023-03-14 07:44:55 +00:00
ibaker
0477d0d338 Restrict the visibility of some DefaultDrmSession methods
These are only used from within the package, so demote them from public
to package-private.

PiperOrigin-RevId: 515029018
2023-03-14 07:40:29 +00:00
tianyifeng
e052b63514 Handle dead object error during writing buffer to AudioTrack
PiperOrigin-RevId: 514989776
2023-03-14 07:36:43 +00:00
tonihei
62c0352416 Use current position code when checking if AudioTrack has pending data
We currently rely on the raw playback head position to check if any
data is pending in the AudioTrack (e.g. to know if the renderer is
still ready). We can use the value returned from getCurrentPositionUs
instead to align the "isReady" logic with the playback position logic.

This has the side effect that getPlaybackHeadPosition position is called
less often when the position is obtained via getTimestamp.

PiperOrigin-RevId: 514747613
2023-03-14 07:34:14 +00:00
ibaker
cb7d565fd4 Add missing @param tags
Dackka generates a warning if a method has at least one `@param` tag,
but not all of them are documented.

#minor-release

PiperOrigin-RevId: 513873453
2023-03-07 11:49:24 +00:00
ibaker
c07cf3dc41 Remove @see tags with <a> tags
These are not supported by Dackka

#minor-release

PiperOrigin-RevId: 513176533
2023-03-01 17:25:48 +00:00
tonihei
a7faa5bfd8 Update translations
#minor-release

PiperOrigin-RevId: 512890813
2023-03-01 17:22:55 +00:00
tonihei
408b4449ff Ensure getPlaybackHeadPosition isn't called if not needed
Once the value returned from AudioTimestampPoller advances, we
only need getPlaybackHeadPosition to sample sync params and
verify the returned timestamp. Both of these happen less often
and we can avoid calling getPlaybackHeadPosition if we don't
actually need it.

PiperOrigin-RevId: 512882170
2023-03-01 17:21:27 +00:00
tonihei
e79b47ccff Fix some playback parameter signalling problems.
Playback parameter signalling can be quite complex because
 (a) the renderer clock often has a delay before it realizes
     that it doesn't support a previously set speed and
 (b) the speed set on media clock sometimes intentionally
     differs from the one surfaced to the user, e.g. during
     live speed adjustment or when overriding ad playback
     speed to 1.0f.

This change fixes two problems related to this signalling:
 1. When resetting the media clock speed at a period transition,
    we don't currently tell the renderers that this happened.
 2. When a delayed speed change update from the media clock is
    pending and the renderer for this media clock is disabled
    before the change can be handled, the pending update becomes
    stale but it still applied later and overrides any other valid
    speed set in the meantime.

Both edge cases are also covered by extended or new player tests.

Issue: google/ExoPlayer#10882

#minor-release

PiperOrigin-RevId: 512658918
2023-03-01 17:18:30 +00:00
tonihei
3970343846 Ensure output format is updated in sync with stream changes.
MediaCodecRenderer currently has two independent paths to trigger
events at stream changes:
 1. Detection of the last output buffer of the old stream to trigger
    onProcessedStreamChange and setting the new output stream offset.
 2. Detection of the first input buffer of the new stream to trigger
    onOutputFormatChanged.
Both events are identical for most media. However, there are two
problematic cases:
  A. (1) happens after (2). This may happen if the declared media
     duration is shorter than the actual last sample timestamp.
  B. (2) is too late and there are output samples between (1) and (2).
     This can happen if the new media outputs samples with a timestamp
     less than the first input timestamp.

This can be made more robust by:
 - Keeping a separate formatQueue for each stream to avoid case A.
 - Force outputting the first format after a stream change to
   avoid case B.

Issue: google/ExoPlayer#8594

#minor-release

PiperOrigin-RevId: 512586838
2023-02-27 18:50:03 +00:00
tonihei
d0cbf0fce8 Add workaround for wrong PerformancePoints on some devices.
Some devices were reported to have wrong PerformancePoint sets
that cause 60 fps to be marked as unsupported even though they
are supported.

Issue: google/ExoPlayer#10898

#minor-release

PiperOrigin-RevId: 512580395
2023-02-27 18:49:00 +00:00
tonihei
7ffcc6f7ea Correctly update output info if previous stream has been fully rendered
The output info for a new stream is marked pending until the last
sample of the previous stream has been processed. However, this fails
if the previous stream has already been fully processed. We need to
detect this case explicitly to avoid signalling the output change one
sample too late.

#minor-release

PiperOrigin-RevId: 512572854
2023-02-27 18:47:20 +00:00
tonihei
0c8ce183fe Use more realistic time values for MediaCodecVideoRendererTest
This test became flaky after ab7e84fb34 because some of the
unrealistic frame times ended up on the same release time.

Using realistic numbers avoids the flakiness.

PiperOrigin-RevId: 512566469
2023-02-27 18:46:28 +00:00
tonihei
93e117928c Do not specify export flags for protected system broadcasts.
Protected system broadcasts should not specify the export flag.
Marking them as NOT_EXPORTED breaks sticky broadcasts in some
cases.

Issue: google/ExoPlayer#10970

#minor-release

PiperOrigin-RevId: 512020154
2023-02-27 18:39:07 +00:00
tianyifeng
672d7494f2 Detect BT devices when getting audio capabilities from the context
PiperOrigin-RevId: 511853003
2023-02-27 18:35:00 +00:00
tonihei
f042012495 Use ArrayDeque for pending output stream changes.
The current logic uses manual array operations to keep track of pending
changes. Modernize this code by using an ArrayDeque and a data class.
This also allows to extend the output stream information in the future.

This also fixes a bug where a position reset accidentally assigns a pending
stream offset instead of keeping the current one.

#minor-release

PiperOrigin-RevId: 511787571
2023-02-27 18:32:03 +00:00
christosts
ab7e84fb34 Skip rendering multiple frames on the same vsync
When rendering frames at a rate higher than the screen refresh rate,
e.g. playing at 8x, the player is releasing multiple frames at the same
release time (nanos) which are then dropped by the platform. The output
buffers are available later and as a result MediaCodec cannot keep up
decoding fast enough.

This change skips releasing multiple video frames on the same vsync
period and proactivelly drops the frame. The frame is counted as skipped
rather than dropped to differentiate with frames dropped due to slow
decoding.

PiperOrigin-RevId: 510964976
2023-02-27 18:07:13 +00:00
tonihei
9eccf09165 Reduce number of calls to AudioTrack.getPlaybackHeadPosition
This call may cause performance overhead in some situations,
for example if the AudioTrack needs to query an offload DSP
for the current position. We don't need to check this multiple
times per doSomeWork iteration as the value is unlikely to
change in any meaningful way.

PiperOrigin-RevId: 510957116
2023-02-27 18:06:20 +00:00
huangdarwin
84acfe7867 Effect: Rename to ScaleAndRotateTransformation
Rename ScaleToFitTransformation to ScaleAndRotateTransformation.

This better represents the operations that can be accomplished using this
effect. The name was originally named ScaleToFit* because it's not obvious how
to scale to fit using OpenGL, and this effect handled the scaling to fit in a way that no other MatrixTransformations did.

However, it's hard to discover how to rotate when skimming names of effects, so
it's probably more useful to convey that this effect rotates, than that it
scales to fit.

PiperOrigin-RevId: 510480078
2023-02-27 18:02:45 +00:00
Googler
5410286955 Update instrumentation to avoid making all constructors public
Previously, any constructors instrumented by Robolectric were made public. This
caused two types of issues:

1) If Android classes had non-public constructors which were made public and
added to the Android API, Robolectric allowed tests to incorrectly use the
constructors on older SDK levels (where they were non-public). This most
commonly occurs for AccessibiltyEvent and AccessibilityNodeInfo.

2) When reflection was used to instantiate classes that were instrumented by
Robolectric, all constructors were accessible, which did not match what
happened when running on an Android test.

Update the instrumentation in Robolectric to prevent making all public
constructors.

PiperOrigin-RevId: 510049123
2023-02-17 11:41:53 +00:00
huangdarwin
cf768329e6 Effect: Rename FrameProcessor
Rename FrameProcessor to VideoFrameProcessor, and GlEffectsFrameProcessor to
DefaultVideoFrameProcessor.

Most changes are semi-mechanical, semi-manual find-replace, preserving case:
* "FrameProc" -> "VideoFrameProc" (ex. FrameProcessor -> VideoFrameProcessor, and
   FrameProcessingException -> VideoFrameProcessingException)
* "GlEffectsVideoFrameProc" -> "DefaultVideoFrameProc"

PiperOrigin-RevId: 509887384
2023-02-17 11:41:06 +00:00
tofunmi
7e33bdfc94 Change FrameProcessor.create() inputTrackType parameter to a boolean
PiperOrigin-RevId: 509808913
2023-02-15 18:17:52 +00:00
Googler
56803bf1ad Add exception cause to thrown exception
PiperOrigin-RevId: 509473556
2023-02-14 10:54:01 +00:00
claincly
749c10ad1e Add error codes to reflect failures in using effects.
PiperOrigin-RevId: 509461955
2023-02-14 09:54:32 +00:00
andrewlewis
68f44915a5 Fix audio generation in silence skipping test
Tests in `SilenceSkippingAudioProcessorTest` used half as many short integers as needed for channel values when generating alternating silence/noise input. Fix this by passing left and right channel input.

PiperOrigin-RevId: 509188074
2023-02-13 12:19:31 +00:00
claincly
519209feac Add public API and render messages for setting effects.
PiperOrigin-RevId: 509165378
2023-02-13 10:15:28 +00:00
christosts
706431059c AsynchronousMediaCodecAdapter: surface queueing errors sooner
The AsynchronousMediaCodecAdapter's queuing thread stores any exceptions
raised by MediaCodec and re-throws them on the next call to
queueInputBuffer()/queueSecureInputBuffer(). However, if MediaCodec
raises and error while queueing, it goes into a failed state and does
not announce available input buffers. If there is no input available
input buffer, the MediaCodecRenderer will never call
queueInputBuffer()/queueSecureInputBuffer(), hence playback is stalled.

This change surfaces the queueing error through the adapter's dequeueing
methods.

PiperOrigin-RevId: 508637346
2023-02-10 13:44:34 +00:00
ibaker
a6dfcf7799 Add null check to ExoPlayerImpl.isTunnelingEnabled
`TrackSelectorResult.rendererConfigurations` can contain null elements:
> A null entry indicates the corresponding renderer should be disabled.

This wasn't caught by the nullness checker because `ExoPlayerImpl` is
currently excluded from analysis.

#minor-release

Issue: google/ExoPlayer#10977
PiperOrigin-RevId: 508619169
2023-02-10 11:44:14 +00:00
Googler
e0ad4ed828 Update SampleQueue.sourceId to be a long rather than an int.
This simplifies usage of 64-bit sequence numbers.

PiperOrigin-RevId: 508107588
2023-02-14 14:23:40 +00:00
Googler
6c7dddbd7f Fix tests affected by Robolectric's constructor visibility bug
Previously, Robolectric's instrumentation updated all constructors to be
public. This caused two main types of problems:

1) When non-public constructors were made public and added to the Android API,
Robolectric allowed tests to incorrectly use the constructors on older SDK
levels (where they were non-public). This most commonly occurs for
AccessibiltyEvent and AccessibilityNodeInfo.

2) When reflection was used to instantiate classes that were instrumented by
Robolectric, all constructors were accessible.

Fix issues across Google3 Robolectric tests that were affected by this issue.
A forthcoming change will fix the instrumentation in Robolectric to prevent
this type of issue from occurring.

Tested:
    TAP --sample ran all affected tests and none failed
    http://test/OCL:507861075:BASE:507805409:1675803313108:f2128fa4
PiperOrigin-RevId: 508087822
2023-02-14 14:21:57 +00:00
michaelkatz
4854e771d7 Encapsulate Opus frames in Ogg during audio offload
PiperOrigin-RevId: 508053559
2023-02-08 14:12:06 +00:00