1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media;
18
19import android.annotation.IntDef;
20import android.annotation.TestApi;
21import android.os.Parcel;
22import android.os.Parcelable;
23
24import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
26
27/**
28 * Structure for source buffering management params.
29 *
30 * Used by {@link MediaPlayer#getBufferingParams()} and
31 * {@link MediaPlayer#setBufferingParams(BufferingParams)}
32 * to control source buffering behavior.
33 *
34 * <p>There are two stages of source buffering in {@link MediaPlayer}: initial buffering
35 * (when {@link MediaPlayer} is being prepared) and rebuffering (when {@link MediaPlayer}
36 * is playing back source). {@link BufferingParams} includes corresponding marks for each
37 * stage of source buffering. The marks are time based (in milliseconds).
38 *
39 * <p>{@link MediaPlayer} source component has default marks which can be queried by
40 * calling {@link MediaPlayer#getBufferingParams()} before any change is made by
41 * {@link MediaPlayer#setBufferingParams()}.
42 * <ul>
43 * <li><strong>initial buffering:</strong> initialMarkMs is used when
44 * {@link MediaPlayer} is being prepared. When cached data amount exceeds this mark
45 * {@link MediaPlayer} is prepared. </li>
46 * <li><strong>rebuffering during playback:</strong> resumePlaybackMarkMs is used when
47 * {@link MediaPlayer} is playing back content.
48 * <ul>
49 * <li> {@link MediaPlayer} has internal mark, namely pausePlaybackMarkMs, to decide when
50 * to pause playback if cached data amount runs low. This internal mark varies based on
51 * type of data source. </li>
52 * <li> When cached data amount exceeds resumePlaybackMarkMs, {@link MediaPlayer} will
53 * resume playback if it has been paused due to low cached data amount. The internal mark
54 * pausePlaybackMarkMs shall be less than resumePlaybackMarkMs. </li>
55 * <li> {@link MediaPlayer} has internal mark, namely pauseRebufferingMarkMs, to decide
56 * when to pause rebuffering. Apparently, this internal mark shall be no less than
57 * resumePlaybackMarkMs. </li>
58 * <li> {@link MediaPlayer} has internal mark, namely resumeRebufferingMarkMs, to decide
59 * when to resume buffering. This internal mark varies based on type of data source. This
60 * mark shall be larger than pausePlaybackMarkMs, and less than pauseRebufferingMarkMs.
61 * </li>
62 * </ul> </li>
63 * </ul>
64 * <p>Users should use {@link Builder} to change {@link BufferingParams}.
65 * @hide
66 */
67@TestApi
68public final class BufferingParams implements Parcelable {
69    private static final int BUFFERING_NO_MARK = -1;
70
71    // params
72    private int mInitialMarkMs = BUFFERING_NO_MARK;
73
74    private int mResumePlaybackMarkMs = BUFFERING_NO_MARK;
75
76    private BufferingParams() {
77    }
78
79    /**
80     * Return initial buffering mark in milliseconds.
81     * @return initial buffering mark in milliseconds
82     */
83    public int getInitialMarkMs() {
84        return mInitialMarkMs;
85    }
86
87    /**
88     * Return the mark in milliseconds for resuming playback.
89     * @return the mark for resuming playback in milliseconds
90     */
91    public int getResumePlaybackMarkMs() {
92        return mResumePlaybackMarkMs;
93    }
94
95    /**
96     * Builder class for {@link BufferingParams} objects.
97     * <p> Here is an example where <code>Builder</code> is used to define the
98     * {@link BufferingParams} to be used by a {@link MediaPlayer} instance:
99     *
100     * <pre class="prettyprint">
101     * BufferingParams myParams = mediaplayer.getDefaultBufferingParams();
102     * myParams = new BufferingParams.Builder(myParams)
103     *         .setInitialMarkMs(10000)
104     *         .setResumePlaybackMarkMs(15000)
105     *         .build();
106     * mediaplayer.setBufferingParams(myParams);
107     * </pre>
108     */
109    public static class Builder {
110        private int mInitialMarkMs = BUFFERING_NO_MARK;
111        private int mResumePlaybackMarkMs = BUFFERING_NO_MARK;
112
113        /**
114         * Constructs a new Builder with the defaults.
115         * By default, all marks are -1.
116         */
117        public Builder() {
118        }
119
120        /**
121         * Constructs a new Builder from a given {@link BufferingParams} instance
122         * @param bp the {@link BufferingParams} object whose data will be reused
123         * in the new Builder.
124         */
125        public Builder(BufferingParams bp) {
126            mInitialMarkMs = bp.mInitialMarkMs;
127            mResumePlaybackMarkMs = bp.mResumePlaybackMarkMs;
128        }
129
130        /**
131         * Combines all of the fields that have been set and return a new
132         * {@link BufferingParams} object. <code>IllegalStateException</code> will be
133         * thrown if there is conflict between fields.
134         * @return a new {@link BufferingParams} object
135         */
136        public BufferingParams build() {
137            BufferingParams bp = new BufferingParams();
138            bp.mInitialMarkMs = mInitialMarkMs;
139            bp.mResumePlaybackMarkMs = mResumePlaybackMarkMs;
140
141            return bp;
142        }
143
144        /**
145         * Sets the time based mark in milliseconds for initial buffering.
146         * @param markMs time based mark in milliseconds
147         * @return the same Builder instance.
148         */
149        public Builder setInitialMarkMs(int markMs) {
150            mInitialMarkMs = markMs;
151            return this;
152        }
153
154        /**
155         * Sets the time based mark in milliseconds for resuming playback.
156         * @param markMs time based mark in milliseconds for resuming playback
157         * @return the same Builder instance.
158         */
159        public Builder setResumePlaybackMarkMs(int markMs) {
160            mResumePlaybackMarkMs = markMs;
161            return this;
162        }
163    }
164
165    private BufferingParams(Parcel in) {
166        mInitialMarkMs = in.readInt();
167        mResumePlaybackMarkMs = in.readInt();
168    }
169
170    public static final Parcelable.Creator<BufferingParams> CREATOR =
171            new Parcelable.Creator<BufferingParams>() {
172                @Override
173                public BufferingParams createFromParcel(Parcel in) {
174                    return new BufferingParams(in);
175                }
176
177                @Override
178                public BufferingParams[] newArray(int size) {
179                    return new BufferingParams[size];
180                }
181            };
182
183
184    @Override
185    public int describeContents() {
186        return 0;
187    }
188
189    @Override
190    public void writeToParcel(Parcel dest, int flags) {
191        dest.writeInt(mInitialMarkMs);
192        dest.writeInt(mResumePlaybackMarkMs);
193    }
194}
195