Some brevity/consistency renaming in source package

SmoothStreaming -> Ss
MediaPresentationDescription -> DashManifest
DashSingleSegmentIndex -> SingleSegmentIndex

Moved DASH and Ss manifest classes to matching
manifest packages for consistency. For Hls the
package is called playlist still, since that's
what they're widely known as.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=127925961
This commit is contained in:
olly 2016-07-20 02:41:11 -07:00 committed by Oliver Woodman
parent fc457e4c1b
commit 722e05b8ba
31 changed files with 274 additions and 279 deletions

View File

@ -43,8 +43,8 @@ import com.google.android.exoplayer2.source.chunk.FormatEvaluator.AdaptiveEvalua
import com.google.android.exoplayer2.source.dash.DashMediaSource; import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource; import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource; import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSmoothStreamingChunkSource; import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingMediaSource; import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.text.CaptionStyleCompat; import com.google.android.exoplayer2.text.CaptionStyleCompat;
import com.google.android.exoplayer2.text.Cue; import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.SubtitleLayout; import com.google.android.exoplayer2.text.SubtitleLayout;
@ -349,16 +349,13 @@ public class PlayerActivity extends Activity implements SurfaceHolder.Callback,
int type = Util.inferContentType(lastPathSegment); int type = Util.inferContentType(lastPathSegment);
switch (type) { switch (type) {
case Util.TYPE_SS: case Util.TYPE_SS:
DefaultSmoothStreamingChunkSource.Factory factory = DefaultSsChunkSource.Factory factory = new DefaultSsChunkSource.Factory(
new DefaultSmoothStreamingChunkSource.Factory(mediaDataSourceFactory, mediaDataSourceFactory, formatEvaluatorFactory);
formatEvaluatorFactory); return new SsMediaSource(uri, manifestDataSourceFactory, factory, mainHandler, eventLogger);
return new SmoothStreamingMediaSource(uri, manifestDataSourceFactory, factory, mainHandler,
eventLogger);
case Util.TYPE_DASH: case Util.TYPE_DASH:
DefaultDashChunkSource.Factory factory2 = new DefaultDashChunkSource.Factory( DefaultDashChunkSource.Factory factory2 = new DefaultDashChunkSource.Factory(
mediaDataSourceFactory, formatEvaluatorFactory); mediaDataSourceFactory, formatEvaluatorFactory);
return new DashMediaSource(uri, mediaDataSourceFactory, factory2, mainHandler, return new DashMediaSource(uri, mediaDataSourceFactory, factory2, mainHandler, eventLogger);
eventLogger);
case Util.TYPE_HLS: case Util.TYPE_HLS:
return new HlsMediaSource(uri, mediaDataSourceFactory, formatEvaluatorFactory, mainHandler, return new HlsMediaSource(uri, mediaDataSourceFactory, formatEvaluatorFactory, mainHandler,
eventLogger); eventLogger);

View File

@ -74,7 +74,7 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
} }
public void testGetAvailableRangeOnLiveWithTimeline() { public void testGetAvailableRangeOnLiveWithTimeline() {
MediaPresentationDescription mpd = buildLiveMpdWithTimeline(LIVE_DURATION_MS, 0); DashManifest mpd = buildLiveMpdWithTimeline(LIVE_DURATION_MS, 0);
DashChunkSource chunkSource = buildDashChunkSource(mpd); DashChunkSource chunkSource = buildDashChunkSource(mpd);
TimeRange availableRange = chunkSource.getAvailableRange(); TimeRange availableRange = chunkSource.getAvailableRange();
checkAvailableRange(availableRange, 0, LIVE_DURATION_MS * 1000); checkAvailableRange(availableRange, 0, LIVE_DURATION_MS * 1000);
@ -90,7 +90,7 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
} }
public void testGetSeekRangeOnMultiPeriodLiveWithTimeline() { public void testGetSeekRangeOnMultiPeriodLiveWithTimeline() {
MediaPresentationDescription mpd = buildMultiPeriodLiveMpdWithTimeline(); DashManifest mpd = buildMultiPeriodLiveMpdWithTimeline();
DashChunkSource chunkSource = buildDashChunkSource(mpd); DashChunkSource chunkSource = buildDashChunkSource(mpd);
TimeRange availableRange = chunkSource.getAvailableRange(); TimeRange availableRange = chunkSource.getAvailableRange();
checkAvailableRange(availableRange, 0, MULTI_PERIOD_LIVE_DURATION_MS * 1000); checkAvailableRange(availableRange, 0, MULTI_PERIOD_LIVE_DURATION_MS * 1000);
@ -113,13 +113,13 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
} }
public void testSegmentRequestSequenceOnMultiPeriodLiveWithTimeline() { public void testSegmentRequestSequenceOnMultiPeriodLiveWithTimeline() {
MediaPresentationDescription mpd = buildMultiPeriodLiveMpdWithTimeline(); DashManifest mpd = buildMultiPeriodLiveMpdWithTimeline();
DashChunkSource chunkSource = buildDashChunkSource(mpd); DashChunkSource chunkSource = buildDashChunkSource(mpd);
checkSegmentRequestSequenceOnMultiPeriodLive(chunkSource); checkSegmentRequestSequenceOnMultiPeriodLive(chunkSource);
} }
public void testSegmentRequestSequenceOnMultiPeriodLiveWithTemplate() { public void testSegmentRequestSequenceOnMultiPeriodLiveWithTemplate() {
MediaPresentationDescription mpd = buildMultiPeriodLiveMpdWithTemplate(); DashManifest mpd = buildMultiPeriodLiveMpdWithTemplate();
DashChunkSource chunkSource = buildDashChunkSource(mpd); DashChunkSource chunkSource = buildDashChunkSource(mpd);
checkSegmentRequestSequenceOnMultiPeriodLive(chunkSource); checkSegmentRequestSequenceOnMultiPeriodLive(chunkSource);
} }
@ -208,30 +208,30 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
return Representation.newInstance(null, 0, REGULAR_VIDEO, segmentBase); return Representation.newInstance(null, 0, REGULAR_VIDEO, segmentBase);
} }
private static MediaPresentationDescription buildMpd(long durationMs, private static DashManifest buildMpd(long durationMs,
List<Representation> representations, boolean live, boolean limitTimeshiftBuffer) { List<Representation> representations, boolean live, boolean limitTimeshiftBuffer) {
AdaptationSet adaptationSet = new AdaptationSet(0, AdaptationSet.TYPE_VIDEO, representations); AdaptationSet adaptationSet = new AdaptationSet(0, AdaptationSet.TYPE_VIDEO, representations);
Period period = new Period(null, 0, Collections.singletonList(adaptationSet)); Period period = new Period(null, 0, Collections.singletonList(adaptationSet));
return new MediaPresentationDescription(AVAILABILITY_START_TIME_MS, durationMs, -1, live, -1, return new DashManifest(AVAILABILITY_START_TIME_MS, durationMs, -1, live, -1,
(limitTimeshiftBuffer) ? LIVE_TIMESHIFT_BUFFER_DEPTH_MS : -1, null, null, (limitTimeshiftBuffer) ? LIVE_TIMESHIFT_BUFFER_DEPTH_MS : -1, null, null,
Collections.singletonList(period)); Collections.singletonList(period));
} }
private static MediaPresentationDescription buildMultiPeriodMpd(long durationMs, private static DashManifest buildMultiPeriodMpd(long durationMs,
List<Period> periods, boolean live, boolean limitTimeshiftBuffer) { List<Period> periods, boolean live, boolean limitTimeshiftBuffer) {
return new MediaPresentationDescription(AVAILABILITY_START_TIME_MS, durationMs, -1, live, -1, return new DashManifest(AVAILABILITY_START_TIME_MS, durationMs, -1, live, -1,
(limitTimeshiftBuffer) ? LIVE_TIMESHIFT_BUFFER_DEPTH_MS : -1, (limitTimeshiftBuffer) ? LIVE_TIMESHIFT_BUFFER_DEPTH_MS : -1,
null, null, periods); null, null, periods);
} }
private static MediaPresentationDescription buildVodMpd() { private static DashManifest buildVodMpd() {
List<Representation> representations = new ArrayList<>(); List<Representation> representations = new ArrayList<>();
representations.add(buildVodRepresentation(TALL_VIDEO)); representations.add(buildVodRepresentation(TALL_VIDEO));
representations.add(buildVodRepresentation(WIDE_VIDEO)); representations.add(buildVodRepresentation(WIDE_VIDEO));
return buildMpd(VOD_DURATION_MS, representations, false, false); return buildMpd(VOD_DURATION_MS, representations, false, false);
} }
private static MediaPresentationDescription buildMultiPeriodVodMpd() { private static DashManifest buildMultiPeriodVodMpd() {
List<Period> periods = new ArrayList<>(); List<Period> periods = new ArrayList<>();
long timeMs = 0; long timeMs = 0;
long periodDurationMs = VOD_DURATION_MS; long periodDurationMs = VOD_DURATION_MS;
@ -246,21 +246,21 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
return buildMultiPeriodMpd(timeMs, periods, false, false); return buildMultiPeriodMpd(timeMs, periods, false, false);
} }
private static MediaPresentationDescription buildLiveMpdWithTimeline(long durationMs, private static DashManifest buildLiveMpdWithTimeline(long durationMs,
long timelineStartTimeMs) { long timelineStartTimeMs) {
Representation representation = buildSegmentTimelineRepresentation( Representation representation = buildSegmentTimelineRepresentation(
durationMs - timelineStartTimeMs, timelineStartTimeMs); durationMs - timelineStartTimeMs, timelineStartTimeMs);
return buildMpd(durationMs, Collections.singletonList(representation), true, false); return buildMpd(durationMs, Collections.singletonList(representation), true, false);
} }
private static MediaPresentationDescription buildLiveMpdWithTemplate(long durationMs, private static DashManifest buildLiveMpdWithTemplate(long durationMs,
boolean limitTimeshiftBuffer) { boolean limitTimeshiftBuffer) {
Representation representation = buildSegmentTemplateRepresentation(); Representation representation = buildSegmentTemplateRepresentation();
return buildMpd(durationMs, Collections.singletonList(representation), true, return buildMpd(durationMs, Collections.singletonList(representation), true,
limitTimeshiftBuffer); limitTimeshiftBuffer);
} }
private static MediaPresentationDescription buildMultiPeriodLiveMpdWithTimeline() { private static DashManifest buildMultiPeriodLiveMpdWithTimeline() {
List<Period> periods = new ArrayList<>(); List<Period> periods = new ArrayList<>();
long periodStartTimeMs = 0; long periodStartTimeMs = 0;
long periodDurationMs = LIVE_DURATION_MS; long periodDurationMs = LIVE_DURATION_MS;
@ -275,7 +275,7 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
return buildMultiPeriodMpd(periodDurationMs, periods, true, false); return buildMultiPeriodMpd(periodDurationMs, periods, true, false);
} }
private static MediaPresentationDescription buildMultiPeriodLiveMpdWithTemplate() { private static DashManifest buildMultiPeriodLiveMpdWithTemplate() {
List<Period> periods = new ArrayList<>(); List<Period> periods = new ArrayList<>();
long periodStartTimeMs = 0; long periodStartTimeMs = 0;
long periodDurationMs = LIVE_DURATION_MS; long periodDurationMs = LIVE_DURATION_MS;
@ -290,14 +290,14 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
return buildMultiPeriodMpd(MULTI_PERIOD_LIVE_DURATION_MS, periods, true, false); return buildMultiPeriodMpd(MULTI_PERIOD_LIVE_DURATION_MS, periods, true, false);
} }
private static DashChunkSource buildDashChunkSource(MediaPresentationDescription mpd) { private static DashChunkSource buildDashChunkSource(DashManifest mpd) {
return buildDashChunkSource(mpd, false, 0); return buildDashChunkSource(mpd, false, 0);
} }
private static DashChunkSource buildDashChunkSource(MediaPresentationDescription mpd, private static DashChunkSource buildDashChunkSource(DashManifest mpd,
boolean startAtLiveEdge, long liveEdgeLatencyMs) { boolean startAtLiveEdge, long liveEdgeLatencyMs) {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ManifestFetcher<MediaPresentationDescription> manifestFetcher = mock(ManifestFetcher.class); ManifestFetcher<DashManifest> manifestFetcher = mock(ManifestFetcher.class);
when(manifestFetcher.getManifest()).thenReturn(mpd); when(manifestFetcher.getManifest()).thenReturn(mpd);
DashChunkSource chunkSource = new DashChunkSource(manifestFetcher, mpd, DashChunkSource chunkSource = new DashChunkSource(manifestFetcher, mpd,
AdaptationSet.TYPE_VIDEO, mock(DataSource.class), null, AdaptationSet.TYPE_VIDEO, mock(DataSource.class), null,
@ -331,7 +331,7 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
private static void checkLiveEdgeConsistencyWithTimeline(long durationMs, long timelineStartMs, private static void checkLiveEdgeConsistencyWithTimeline(long durationMs, long timelineStartMs,
long liveEdgeLatencyMs, long seekPositionMs, long availableRangeStartMs, long liveEdgeLatencyMs, long seekPositionMs, long availableRangeStartMs,
long availableRangeEndMs, long chunkStartTimeMs, long chunkEndTimeMs) { long availableRangeEndMs, long chunkStartTimeMs, long chunkEndTimeMs) {
MediaPresentationDescription mpd = buildLiveMpdWithTimeline(durationMs, timelineStartMs); DashManifest mpd = buildLiveMpdWithTimeline(durationMs, timelineStartMs);
checkLiveEdgeConsistency(mpd, liveEdgeLatencyMs, seekPositionMs, checkLiveEdgeConsistency(mpd, liveEdgeLatencyMs, seekPositionMs,
availableRangeStartMs, availableRangeEndMs, chunkStartTimeMs, chunkEndTimeMs); availableRangeStartMs, availableRangeEndMs, chunkStartTimeMs, chunkEndTimeMs);
} }
@ -339,7 +339,7 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
private static void checkLiveEdgeConsistencyWithTemplateAndUnlimitedTimeshift(long durationMs, private static void checkLiveEdgeConsistencyWithTemplateAndUnlimitedTimeshift(long durationMs,
long liveEdgeLatencyMs, long availablePositionMs, long availableRangeEndMs, long liveEdgeLatencyMs, long availablePositionMs, long availableRangeEndMs,
long chunkStartTimeMs, long chunkEndTimeMs) { long chunkStartTimeMs, long chunkEndTimeMs) {
MediaPresentationDescription mpd = buildLiveMpdWithTemplate(durationMs, false); DashManifest mpd = buildLiveMpdWithTemplate(durationMs, false);
checkLiveEdgeConsistency(mpd, liveEdgeLatencyMs, availablePositionMs, 0, checkLiveEdgeConsistency(mpd, liveEdgeLatencyMs, availablePositionMs, 0,
availableRangeEndMs, chunkStartTimeMs, chunkEndTimeMs); availableRangeEndMs, chunkStartTimeMs, chunkEndTimeMs);
} }
@ -347,12 +347,12 @@ public class DashChunkSourceTest extends InstrumentationTestCase {
private static void checkLiveEdgeConsistencyWithTemplateAndLimitedTimeshift(long durationMs, private static void checkLiveEdgeConsistencyWithTemplateAndLimitedTimeshift(long durationMs,
long liveEdgeLatencyMs, long seekPositionMs, long availableRangeStartMs, long liveEdgeLatencyMs, long seekPositionMs, long availableRangeStartMs,
long availableRangeEndMs, long chunkStartTimeMs, long chunkEndTimeMs) { long availableRangeEndMs, long chunkStartTimeMs, long chunkEndTimeMs) {
MediaPresentationDescription mpd = buildLiveMpdWithTemplate(durationMs, true); DashManifest mpd = buildLiveMpdWithTemplate(durationMs, true);
checkLiveEdgeConsistency(mpd, liveEdgeLatencyMs, seekPositionMs, availableRangeStartMs, checkLiveEdgeConsistency(mpd, liveEdgeLatencyMs, seekPositionMs, availableRangeStartMs,
availableRangeEndMs, chunkStartTimeMs, chunkEndTimeMs); availableRangeEndMs, chunkStartTimeMs, chunkEndTimeMs);
} }
private static void checkLiveEdgeConsistency(MediaPresentationDescription mpd, private static void checkLiveEdgeConsistency(DashManifest mpd,
long liveEdgeLatencyMs, long seekPositionMs, long availableRangeStartMs, long liveEdgeLatencyMs, long seekPositionMs, long availableRangeStartMs,
long availableRangeEndMs, long chunkStartTimeMs, long chunkEndTimeMs) { long availableRangeEndMs, long chunkStartTimeMs, long chunkEndTimeMs) {
DashChunkSource chunkSource = buildDashChunkSource(mpd, true, liveEdgeLatencyMs); DashChunkSource chunkSource = buildDashChunkSource(mpd, true, liveEdgeLatencyMs);

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.testutil.TestUtil;
import android.net.Uri;
import android.test.InstrumentationTestCase;
import java.io.IOException;
/**
* Unit tests for {@link DashManifestParser}.
*/
public class DashManifestParserTest extends InstrumentationTestCase {
private static final String SAMPLE_MPD_1 = "dash/sample_mpd_1";
private static final String SAMPLE_MPD_2_UNKNOWN_MIME_TYPE =
"dash/sample_mpd_2_unknown_mime_type";
/**
* Simple test to ensure the sample manifests parse without any exceptions being thrown.
*/
public void testParseMediaPresentationDescription() throws IOException {
DashManifestParser parser = new DashManifestParser();
parser.parse(Uri.parse("https://example.com/test.mpd"),
TestUtil.getInputStream(getInstrumentation(), SAMPLE_MPD_1));
parser.parse(Uri.parse("https://example.com/test.mpd"),
TestUtil.getInputStream(getInstrumentation(), SAMPLE_MPD_2_UNKNOWN_MIME_TYPE));
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import junit.framework.TestCase; import junit.framework.TestCase;

View File

@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.SingleSegmentBase; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import junit.framework.TestCase; import junit.framework.TestCase;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import junit.framework.TestCase; import junit.framework.TestCase;

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.dash.mpd;
import android.net.Uri;
import android.test.InstrumentationTestCase;
import java.io.IOException;
import java.io.InputStream;
/**
* Unit tests for {@link MediaPresentationDescriptionParser}.
*/
public class MediaPresentationDescriptionParserTest extends InstrumentationTestCase {
private static final String SAMPLE_MPD_1 = "dash/sample_mpd_1";
private static final String SAMPLE_MPD_2_UNKNOWN_MIME_TYPE =
"dash/sample_mpd_2_unknown_mime_type";
public void testParseMediaPresentationDescription() throws IOException {
MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser();
InputStream inputStream =
getInstrumentation().getContext().getResources().getAssets().open(SAMPLE_MPD_1);
// Simple test to ensure that the sample manifest parses without throwing any exceptions.
parser.parse(Uri.parse("https://example.com/test.mpd"), inputStream);
}
public void testParseMediaPresentationDescriptionWithUnknownMimeType() throws IOException {
MediaPresentationDescriptionParser parser = new MediaPresentationDescriptionParser();
InputStream inputStream = getInstrumentation().getContext().getResources().getAssets()
.open(SAMPLE_MPD_2_UNKNOWN_MIME_TYPE);
// Simple test to ensure that the sample manifest with an unknown mime type parses without
// throwing any exceptions.
parser.parse(Uri.parse("https://example.com/test.mpd"), inputStream);
}
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.smoothstreaming;
import android.net.Uri;
import android.test.InstrumentationTestCase;
import java.io.IOException;
import java.io.InputStream;
/**
* Unit tests for {@link SmoothStreamingManifestParser}.
*/
public class SmoothStreamingManifestParserTest extends InstrumentationTestCase {
private static final String SAMPLE_ISMC_1 = "smoothstreaming/sample_ismc_1";
private static final String SAMPLE_ISMC_2 = "smoothstreaming/sample_ismc_2";
public void testParseSmoothStreamingManifest() throws IOException {
SmoothStreamingManifestParser parser = new SmoothStreamingManifestParser();
// Simple test to ensure that the sample manifest parses without throwing any exceptions.
// SystemID UUID in the manifest is not wrapped in braces.
InputStream inputStream1 =
getInstrumentation().getContext().getResources().getAssets().open(SAMPLE_ISMC_1);
parser.parse(Uri.parse("https://example.com/test.ismc"), inputStream1);
// Simple test to ensure that the sample manifest parses without throwing any exceptions.
// SystemID UUID in the manifest is wrapped in braces.
InputStream inputStream2 =
getInstrumentation().getContext().getResources().getAssets().open(SAMPLE_ISMC_2);
parser.parse(Uri.parse("https://example.com/test.ismc"), inputStream2);
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source.smoothstreaming.manifest;
import com.google.android.exoplayer2.testutil.TestUtil;
import android.net.Uri;
import android.test.InstrumentationTestCase;
import java.io.IOException;
/**
* Unit tests for {@link SsManifestParser}.
*/
public final class SsManifestParserTest extends InstrumentationTestCase {
private static final String SAMPLE_ISMC_1 = "smoothstreaming/sample_ismc_1";
private static final String SAMPLE_ISMC_2 = "smoothstreaming/sample_ismc_2";
/**
* Simple test to ensure the sample manifests parse without any exceptions being thrown.
*/
public void testParseSmoothStreamingManifest() throws IOException {
SsManifestParser parser = new SsManifestParser();
parser.parse(Uri.parse("https://example.com/test.ismc"),
TestUtil.getInputStream(getInstrumentation(), SAMPLE_ISMC_1));
parser.parse(Uri.parse("https://example.com/test.ismc"),
TestUtil.getInputStream(getInstrumentation(), SAMPLE_ISMC_2));
}
}

View File

@ -17,7 +17,7 @@ package com.google.android.exoplayer2.source.dash;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.chunk.ChunkSource; import com.google.android.exoplayer2.source.chunk.ChunkSource;
import com.google.android.exoplayer2.source.dash.mpd.MediaPresentationDescription; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
/** /**
@ -27,12 +27,12 @@ public interface DashChunkSource extends ChunkSource {
interface Factory { interface Factory {
DashChunkSource createDashChunkSource(Loader manifestLoader, DashChunkSource createDashChunkSource(Loader manifestLoader, DashManifest manifest,
MediaPresentationDescription manifest, int periodIndex, int adaptationSetIndex, int periodIndex, int adaptationSetIndex, TrackGroup trackGroup, int[] tracks,
TrackGroup trackGroup, int[] tracks, long elapsedRealtimeOffsetMs); long elapsedRealtimeOffsetMs);
} }
void updateManifest(MediaPresentationDescription newManifest, int periodIndex); void updateManifest(DashManifest newManifest, int periodIndex);
} }

View File

@ -25,10 +25,10 @@ import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream; import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
import com.google.android.exoplayer2.source.dash.mpd.AdaptationSet; import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
import com.google.android.exoplayer2.source.dash.mpd.MediaPresentationDescription; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.mpd.Period; import com.google.android.exoplayer2.source.dash.manifest.Period;
import com.google.android.exoplayer2.source.dash.mpd.Representation; import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
@ -58,11 +58,11 @@ import java.util.List;
private CompositeSequenceableLoader sequenceableLoader; private CompositeSequenceableLoader sequenceableLoader;
private Callback callback; private Callback callback;
private Allocator allocator; private Allocator allocator;
private MediaPresentationDescription manifest; private DashManifest manifest;
private int index; private int index;
private Period period; private Period period;
public DashMediaPeriod(MediaPresentationDescription manifest, int index, public DashMediaPeriod(DashManifest manifest, int index,
DashChunkSource.Factory chunkSourceFactory, int minLoadableRetryCount, DashChunkSource.Factory chunkSourceFactory, int minLoadableRetryCount,
EventDispatcher eventDispatcher, long elapsedRealtimeOffset, Loader loader) { EventDispatcher eventDispatcher, long elapsedRealtimeOffset, Loader loader) {
this.manifest = manifest; this.manifest = manifest;
@ -79,7 +79,7 @@ import java.util.List;
trackGroupAdaptationSetIndices = trackGroupsAndAdaptationSetIndices.second; trackGroupAdaptationSetIndices = trackGroupsAndAdaptationSetIndices.second;
} }
public void updateManifest(MediaPresentationDescription manifest, int index) { public void updateManifest(DashManifest manifest, int index) {
this.manifest = manifest; this.manifest = manifest;
this.index = index; this.index = index;
period = manifest.getPeriod(index); period = manifest.getPeriod(index);

View File

@ -21,9 +21,9 @@ import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener;
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.dash.mpd.MediaPresentationDescription; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.mpd.MediaPresentationDescriptionParser; import com.google.android.exoplayer2.source.dash.manifest.DashManifestParser;
import com.google.android.exoplayer2.source.dash.mpd.UtcTimingElement; import com.google.android.exoplayer2.source.dash.manifest.UtcTimingElement;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
@ -59,7 +59,7 @@ public final class DashMediaSource implements MediaSource {
private final DashChunkSource.Factory chunkSourceFactory; private final DashChunkSource.Factory chunkSourceFactory;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final MediaPresentationDescriptionParser manifestParser; private final DashManifestParser manifestParser;
private final ManifestCallback manifestCallback; private final ManifestCallback manifestCallback;
private DataSource dataSource; private DataSource dataSource;
@ -68,7 +68,7 @@ public final class DashMediaSource implements MediaSource {
private Uri manifestUri; private Uri manifestUri;
private long manifestLoadStartTimestamp; private long manifestLoadStartTimestamp;
private long manifestLoadEndTimestamp; private long manifestLoadEndTimestamp;
private MediaPresentationDescription manifest; private DashManifest manifest;
private Handler manifestRefreshHandler; private Handler manifestRefreshHandler;
private DashMediaPeriod[] periods; private DashMediaPeriod[] periods;
private long elapsedRealtimeOffset; private long elapsedRealtimeOffset;
@ -88,7 +88,7 @@ public final class DashMediaSource implements MediaSource {
this.chunkSourceFactory = chunkSourceFactory; this.chunkSourceFactory = chunkSourceFactory;
this.minLoadableRetryCount = minLoadableRetryCount; this.minLoadableRetryCount = minLoadableRetryCount;
eventDispatcher = new EventDispatcher(eventHandler, eventListener); eventDispatcher = new EventDispatcher(eventHandler, eventListener);
manifestParser = new MediaPresentationDescriptionParser(); manifestParser = new DashManifestParser();
manifestCallback = new ManifestCallback(); manifestCallback = new ManifestCallback();
} }
@ -138,7 +138,7 @@ public final class DashMediaSource implements MediaSource {
// Loadable callbacks. // Loadable callbacks.
/* package */ void onManifestLoadCompleted(ParsingLoadable<MediaPresentationDescription> loadable, /* package */ void onManifestLoadCompleted(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs) { long elapsedRealtimeMs, long loadDurationMs) {
eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, elapsedRealtimeMs, eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, elapsedRealtimeMs,
loadDurationMs, loadable.bytesLoaded()); loadDurationMs, loadable.bytesLoaded());
@ -162,7 +162,7 @@ public final class DashMediaSource implements MediaSource {
} }
} }
/* package */ int onManifestLoadError(ParsingLoadable<MediaPresentationDescription> loadable, /* package */ int onManifestLoadError(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs, IOException error) { long elapsedRealtimeMs, long loadDurationMs, IOException error) {
boolean isFatal = error instanceof ParserException; boolean isFatal = error instanceof ParserException;
eventDispatcher.loadError(loadable.dataSpec, loadable.type, elapsedRealtimeMs, loadDurationMs, eventDispatcher.loadError(loadable.dataSpec, loadable.type, elapsedRealtimeMs, loadDurationMs,
@ -278,22 +278,22 @@ public final class DashMediaSource implements MediaSource {
} }
private final class ManifestCallback implements private final class ManifestCallback implements
Loader.Callback<ParsingLoadable<MediaPresentationDescription>> { Loader.Callback<ParsingLoadable<DashManifest>> {
@Override @Override
public void onLoadCompleted(ParsingLoadable<MediaPresentationDescription> loadable, public void onLoadCompleted(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs) { long elapsedRealtimeMs, long loadDurationMs) {
onManifestLoadCompleted(loadable, elapsedRealtimeMs, loadDurationMs); onManifestLoadCompleted(loadable, elapsedRealtimeMs, loadDurationMs);
} }
@Override @Override
public void onLoadCanceled(ParsingLoadable<MediaPresentationDescription> loadable, public void onLoadCanceled(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs, boolean released) { long elapsedRealtimeMs, long loadDurationMs, boolean released) {
DashMediaSource.this.onLoadCanceled(loadable, elapsedRealtimeMs, loadDurationMs); DashMediaSource.this.onLoadCanceled(loadable, elapsedRealtimeMs, loadDurationMs);
} }
@Override @Override
public int onLoadError(ParsingLoadable<MediaPresentationDescription> loadable, public int onLoadError(ParsingLoadable<DashManifest> loadable,
long elapsedRealtimeMs, long loadDurationMs, IOException error) { long elapsedRealtimeMs, long loadDurationMs, IOException error) {
return onManifestLoadError(loadable, elapsedRealtimeMs, loadDurationMs, error); return onManifestLoadError(loadable, elapsedRealtimeMs, loadDurationMs, error);
} }

View File

@ -16,7 +16,7 @@
package com.google.android.exoplayer2.source.dash; package com.google.android.exoplayer2.source.dash;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.dash.mpd.RangedUri; import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
/** /**
* Indexes the segments within a media stream. * Indexes the segments within a media stream.

View File

@ -16,7 +16,7 @@
package com.google.android.exoplayer2.source.dash; package com.google.android.exoplayer2.source.dash;
import com.google.android.exoplayer2.extractor.ChunkIndex; import com.google.android.exoplayer2.extractor.ChunkIndex;
import com.google.android.exoplayer2.source.dash.mpd.RangedUri; import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
/** /**
* An implementation of {@link DashSegmentIndex} that wraps a {@link ChunkIndex} parsed from a * An implementation of {@link DashSegmentIndex} that wraps a {@link ChunkIndex} parsed from a

View File

@ -33,9 +33,9 @@ import com.google.android.exoplayer2.source.chunk.FormatEvaluator.Evaluation;
import com.google.android.exoplayer2.source.chunk.InitializationChunk; import com.google.android.exoplayer2.source.chunk.InitializationChunk;
import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk; import com.google.android.exoplayer2.source.chunk.SingleSampleMediaChunk;
import com.google.android.exoplayer2.source.dash.mpd.MediaPresentationDescription; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
import com.google.android.exoplayer2.source.dash.mpd.RangedUri; import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
import com.google.android.exoplayer2.source.dash.mpd.Representation; import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException; import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCodeException;
@ -66,9 +66,9 @@ public class DefaultDashChunkSource implements DashChunkSource {
} }
@Override @Override
public DashChunkSource createDashChunkSource(Loader manifestLoader, public DashChunkSource createDashChunkSource(Loader manifestLoader, DashManifest manifest,
MediaPresentationDescription manifest, int periodIndex, int adaptationSetIndex, int periodIndex, int adaptationSetIndex, TrackGroup trackGroup, int[] tracks,
TrackGroup trackGroup, int[] tracks, long elapsedRealtimeOffsetMs) { long elapsedRealtimeOffsetMs) {
FormatEvaluator adaptiveEvaluator = tracks.length > 1 FormatEvaluator adaptiveEvaluator = tracks.length > 1
? formatEvaluatorFactory.createFormatEvaluator() : null; ? formatEvaluatorFactory.createFormatEvaluator() : null;
DataSource dataSource = dataSourceFactory.createDataSource(); DataSource dataSource = dataSourceFactory.createDataSource();
@ -89,7 +89,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
private final long elapsedRealtimeOffsetUs; private final long elapsedRealtimeOffsetUs;
private final Evaluation evaluation; private final Evaluation evaluation;
private MediaPresentationDescription manifest; private DashManifest manifest;
private boolean lastChunkWasInitialization; private boolean lastChunkWasInitialization;
private IOException fatalError; private IOException fatalError;
@ -108,10 +108,9 @@ public class DefaultDashChunkSource implements DashChunkSource {
* server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, specified * server-side unix time and {@link SystemClock#elapsedRealtime()} in milliseconds, specified
* as the server's unix time minus the local elapsed time. If unknown, set to 0. * as the server's unix time minus the local elapsed time. If unknown, set to 0.
*/ */
public DefaultDashChunkSource(Loader manifestLoader, MediaPresentationDescription manifest, public DefaultDashChunkSource(Loader manifestLoader, DashManifest manifest, int periodIndex,
int periodIndex, int adaptationSetIndex, TrackGroup trackGroup, int[] tracks, int adaptationSetIndex, TrackGroup trackGroup, int[] tracks, DataSource dataSource,
DataSource dataSource, FormatEvaluator adaptiveFormatEvaluator, FormatEvaluator adaptiveFormatEvaluator, long elapsedRealtimeOffsetMs) {
long elapsedRealtimeOffsetMs) {
this.manifestLoader = manifestLoader; this.manifestLoader = manifestLoader;
this.manifest = manifest; this.manifest = manifest;
this.adaptationSetIndex = adaptationSetIndex; this.adaptationSetIndex = adaptationSetIndex;
@ -143,7 +142,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
} }
@Override @Override
public void updateManifest(MediaPresentationDescription newManifest, int periodIndex) { public void updateManifest(DashManifest newManifest, int periodIndex) {
try { try {
manifest = newManifest; manifest = newManifest;
long periodDurationUs = getPeriodDurationUs(periodIndex); long periodDurationUs = getPeriodDurationUs(periodIndex);

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import android.net.Uri; import android.net.Uri;
@ -23,7 +23,7 @@ import java.util.List;
/** /**
* Represents a DASH media presentation description (mpd). * Represents a DASH media presentation description (mpd).
*/ */
public class MediaPresentationDescription { public class DashManifest {
public final long availabilityStartTime; public final long availabilityStartTime;
@ -43,7 +43,7 @@ public class MediaPresentationDescription {
private final List<Period> periods; private final List<Period> periods;
public MediaPresentationDescription(long availabilityStartTime, long duration, long minBufferTime, public DashManifest(long availabilityStartTime, long duration, long minBufferTime,
boolean dynamic, long minUpdatePeriod, long timeShiftBufferDepth, UtcTimingElement utcTiming, boolean dynamic, long minUpdatePeriod, long timeShiftBufferDepth, UtcTimingElement utcTiming,
Uri location, List<Period> periods) { Uri location, List<Period> periods) {
this.availabilityStartTime = availabilityStartTime; this.availabilityStartTime = availabilityStartTime;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
@ -21,10 +21,10 @@ import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil; import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil;
import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.SegmentList; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentList;
import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.SegmentTemplate; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentTemplate;
import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.SegmentTimelineElement; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SegmentTimelineElement;
import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.SingleSegmentBase; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
@ -55,8 +55,8 @@ import java.util.regex.Pattern;
/** /**
* A parser of media presentation description files. * A parser of media presentation description files.
*/ */
public class MediaPresentationDescriptionParser extends DefaultHandler public class DashManifestParser extends DefaultHandler
implements ParsingLoadable.Parser<MediaPresentationDescription> { implements ParsingLoadable.Parser<DashManifest> {
private static final String TAG = "MpdParser"; private static final String TAG = "MpdParser";
@ -66,16 +66,16 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
private final XmlPullParserFactory xmlParserFactory; private final XmlPullParserFactory xmlParserFactory;
/** /**
* Equivalent to calling {@code new MediaPresentationDescriptionParser(null)}. * Equivalent to calling {@code new DashManifestParser(null)}.
*/ */
public MediaPresentationDescriptionParser() { public DashManifestParser() {
this(null); this(null);
} }
/** /**
* @param contentId An optional content identifier to include in the parsed manifest. * @param contentId An optional content identifier to include in the parsed manifest.
*/ */
public MediaPresentationDescriptionParser(String contentId) { public DashManifestParser(String contentId) {
this.contentId = contentId; this.contentId = contentId;
try { try {
xmlParserFactory = XmlPullParserFactory.newInstance(); xmlParserFactory = XmlPullParserFactory.newInstance();
@ -87,7 +87,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
// MPD parsing. // MPD parsing.
@Override @Override
public MediaPresentationDescription parse(Uri uri, InputStream inputStream) throws IOException { public DashManifest parse(Uri uri, InputStream inputStream) throws IOException {
try { try {
XmlPullParser xpp = xmlParserFactory.newPullParser(); XmlPullParser xpp = xmlParserFactory.newPullParser();
xpp.setInput(inputStream, null); xpp.setInput(inputStream, null);
@ -102,7 +102,7 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
} }
} }
protected MediaPresentationDescription parseMediaPresentationDescription(XmlPullParser xpp, protected DashManifest parseMediaPresentationDescription(XmlPullParser xpp,
String baseUrl) throws XmlPullParserException, IOException, ParseException { String baseUrl) throws XmlPullParserException, IOException, ParseException {
long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", -1); long availabilityStartTime = parseDateTime(xpp, "availabilityStartTime", -1);
long durationMs = parseDuration(xpp, "mediaPresentationDuration", -1); long durationMs = parseDuration(xpp, "mediaPresentationDuration", -1);
@ -165,11 +165,10 @@ public class MediaPresentationDescriptionParser extends DefaultHandler
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods); dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods);
} }
protected MediaPresentationDescription buildMediaPresentationDescription( protected DashManifest buildMediaPresentationDescription(long availabilityStartTime,
long availabilityStartTime, long durationMs, long minBufferTimeMs, boolean dynamic, long durationMs, long minBufferTimeMs, boolean dynamic, long minUpdateTimeMs,
long minUpdateTimeMs, long timeShiftBufferDepthMs, UtcTimingElement utcTiming, long timeShiftBufferDepthMs, UtcTimingElement utcTiming, Uri location, List<Period> periods) {
Uri location, List<Period> periods) { return new DashManifest(availabilityStartTime, durationMs, minBufferTimeMs,
return new MediaPresentationDescription(availabilityStartTime, durationMs, minBufferTimeMs,
dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods); dynamic, minUpdateTimeMs, timeShiftBufferDepthMs, utcTiming, location, periods);
} }

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.UriUtil; import com.google.android.exoplayer2.util.UriUtil;

View File

@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex; import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.MultiSegmentBase; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.MultiSegmentBase;
import com.google.android.exoplayer2.source.dash.mpd.SegmentBase.SingleSegmentBase; import com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase;
import android.net.Uri; import android.net.Uri;
@ -156,7 +156,7 @@ public abstract class Representation {
public final long contentLength; public final long contentLength;
private final RangedUri indexUri; private final RangedUri indexUri;
private final DashSingleSegmentIndex segmentIndex; private final SingleSegmentIndex segmentIndex;
/** /**
* @param contentId Identifies the piece of content to which this representation belongs. * @param contentId Identifies the piece of content to which this representation belongs.
@ -198,7 +198,7 @@ public abstract class Representation {
// If we have an index uri then the index is defined externally, and we shouldn't return one // If we have an index uri then the index is defined externally, and we shouldn't return one
// directly. If we don't, then we can't do better than an index defining a single segment. // directly. If we don't, then we can't do better than an index defining a single segment.
segmentIndex = indexUri != null ? null segmentIndex = indexUri != null ? null
: new DashSingleSegmentIndex(new RangedUri(segmentBase.uri, null, 0, contentLength)); : new SingleSegmentIndex(new RangedUri(segmentBase.uri, null, 0, contentLength));
} }
@Override @Override

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex; import com.google.android.exoplayer2.source.dash.DashSegmentIndex;

View File

@ -13,21 +13,21 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import com.google.android.exoplayer2.source.dash.DashSegmentIndex; import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
/** /**
* A {@link DashSegmentIndex} that defines a single segment. * A {@link DashSegmentIndex} that defines a single segment.
*/ */
/* package */ final class DashSingleSegmentIndex implements DashSegmentIndex { /* package */ final class SingleSegmentIndex implements DashSegmentIndex {
private final RangedUri uri; private final RangedUri uri;
/** /**
* @param uri A {@link RangedUri} defining the location of the segment data. * @param uri A {@link RangedUri} defining the location of the segment data.
*/ */
public DashSingleSegmentIndex(RangedUri uri) { public SingleSegmentIndex(RangedUri uri) {
this.uri = uri; this.uri = uri;
} }

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
import java.util.Locale; import java.util.Locale;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.dash.mpd; package com.google.android.exoplayer2.source.dash.manifest;
/** /**
* Represents a UTCTiming element. * Represents a UTCTiming element.

View File

@ -30,7 +30,8 @@ import com.google.android.exoplayer2.source.chunk.ContainerMediaChunk;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator; import com.google.android.exoplayer2.source.chunk.FormatEvaluator;
import com.google.android.exoplayer2.source.chunk.FormatEvaluator.Evaluation; import com.google.android.exoplayer2.source.chunk.FormatEvaluator.Evaluation;
import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingManifest.StreamElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
@ -43,11 +44,11 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
* A default {@link SmoothStreamingChunkSource} implementation. * A default {@link SsChunkSource} implementation.
*/ */
public class DefaultSmoothStreamingChunkSource implements SmoothStreamingChunkSource { public class DefaultSsChunkSource implements SsChunkSource {
public static final class Factory implements SmoothStreamingChunkSource.Factory { public static final class Factory implements SsChunkSource.Factory {
private final FormatEvaluator.Factory formatEvaluatorFactory; private final FormatEvaluator.Factory formatEvaluatorFactory;
private final DataSource.Factory dataSourceFactory; private final DataSource.Factory dataSourceFactory;
@ -59,13 +60,13 @@ public class DefaultSmoothStreamingChunkSource implements SmoothStreamingChunkSo
} }
@Override @Override
public SmoothStreamingChunkSource createChunkSource(Loader manifestLoader, public SsChunkSource createChunkSource(Loader manifestLoader, SsManifest manifest,
SmoothStreamingManifest manifest, int elementIndex, TrackGroup trackGroup, int[] tracks, int elementIndex, TrackGroup trackGroup, int[] tracks,
TrackEncryptionBox[] trackEncryptionBoxes) { TrackEncryptionBox[] trackEncryptionBoxes) {
FormatEvaluator adaptiveEvaluator = tracks.length > 1 FormatEvaluator adaptiveEvaluator = tracks.length > 1
? formatEvaluatorFactory.createFormatEvaluator() : null; ? formatEvaluatorFactory.createFormatEvaluator() : null;
DataSource dataSource = dataSourceFactory.createDataSource(); DataSource dataSource = dataSourceFactory.createDataSource();
return new DefaultSmoothStreamingChunkSource(manifestLoader, manifest, elementIndex, return new DefaultSsChunkSource(manifestLoader, manifest, elementIndex,
trackGroup, tracks, dataSource, adaptiveEvaluator, trackGroup, tracks, dataSource, adaptiveEvaluator,
trackEncryptionBoxes); trackEncryptionBoxes);
} }
@ -82,7 +83,7 @@ public class DefaultSmoothStreamingChunkSource implements SmoothStreamingChunkSo
private final Evaluation evaluation; private final Evaluation evaluation;
private final FormatEvaluator adaptiveFormatEvaluator; private final FormatEvaluator adaptiveFormatEvaluator;
private SmoothStreamingManifest manifest; private SsManifest manifest;
private int currentManifestChunkOffset; private int currentManifestChunkOffset;
private IOException fatalError; private IOException fatalError;
@ -97,8 +98,8 @@ public class DefaultSmoothStreamingChunkSource implements SmoothStreamingChunkSo
* @param adaptiveFormatEvaluator For adaptive tracks, selects from the available formats. * @param adaptiveFormatEvaluator For adaptive tracks, selects from the available formats.
* @param trackEncryptionBoxes Track encryption boxes for the stream. * @param trackEncryptionBoxes Track encryption boxes for the stream.
*/ */
public DefaultSmoothStreamingChunkSource(Loader manifestLoader, SmoothStreamingManifest manifest, public DefaultSsChunkSource(Loader manifestLoader, SsManifest manifest, int elementIndex,
int elementIndex, TrackGroup trackGroup, int[] tracks, DataSource dataSource, TrackGroup trackGroup, int[] tracks, DataSource dataSource,
FormatEvaluator adaptiveFormatEvaluator, TrackEncryptionBox[] trackEncryptionBoxes) { FormatEvaluator adaptiveFormatEvaluator, TrackEncryptionBox[] trackEncryptionBoxes) {
this.manifestLoader = manifestLoader; this.manifestLoader = manifestLoader;
this.manifest = manifest; this.manifest = manifest;
@ -136,7 +137,7 @@ public class DefaultSmoothStreamingChunkSource implements SmoothStreamingChunkSo
} }
@Override @Override
public void updateManifest(SmoothStreamingManifest newManifest) { public void updateManifest(SsManifest newManifest) {
StreamElement currentElement = manifest.streamElements[elementIndex]; StreamElement currentElement = manifest.streamElements[elementIndex];
int currentElementChunkCount = currentElement.chunkCount; int currentElementChunkCount = currentElement.chunkCount;
StreamElement newElement = newManifest.streamElements[elementIndex]; StreamElement newElement = newManifest.streamElements[elementIndex];

View File

@ -18,21 +18,21 @@ package com.google.android.exoplayer2.source.smoothstreaming;
import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox; import com.google.android.exoplayer2.extractor.mp4.TrackEncryptionBox;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.chunk.ChunkSource; import com.google.android.exoplayer2.source.chunk.ChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.upstream.Loader; import com.google.android.exoplayer2.upstream.Loader;
/** /**
* A {@link ChunkSource} for SmoothStreaming. * A {@link ChunkSource} for SmoothStreaming.
*/ */
public interface SmoothStreamingChunkSource extends ChunkSource { public interface SsChunkSource extends ChunkSource {
interface Factory { interface Factory {
SmoothStreamingChunkSource createChunkSource(Loader manifestLoader, SsChunkSource createChunkSource(Loader manifestLoader, SsManifest manifest, int elementIndex,
SmoothStreamingManifest manifest, int elementIndex, TrackGroup trackGroup, int[] tracks, TrackGroup trackGroup, int[] tracks, TrackEncryptionBox[] trackEncryptionBoxes);
TrackEncryptionBox[] trackEncryptionBoxes);
} }
void updateManifest(SmoothStreamingManifest newManifest); void updateManifest(SsManifest newManifest);
} }

View File

@ -29,8 +29,10 @@ import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.ChunkSampleStream; import com.google.android.exoplayer2.source.chunk.ChunkSampleStream;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingManifest.ProtectionElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingManifest.StreamElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.ProtectionElement;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser;
import com.google.android.exoplayer2.trackselection.TrackSelection; import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
@ -51,9 +53,9 @@ import java.util.List;
/** /**
* A SmoothStreaming {@link MediaSource}. * A SmoothStreaming {@link MediaSource}.
*/ */
public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSource, public final class SsMediaSource implements MediaPeriod, MediaSource,
SequenceableLoader.Callback<ChunkSampleStream<SmoothStreamingChunkSource>>, SequenceableLoader.Callback<ChunkSampleStream<SsChunkSource>>,
Loader.Callback<ParsingLoadable<SmoothStreamingManifest>> { Loader.Callback<ParsingLoadable<SsManifest>> {
/** /**
* The default minimum number of times to retry loading data prior to failing. * The default minimum number of times to retry loading data prior to failing.
@ -65,18 +67,18 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
private final Uri manifestUri; private final Uri manifestUri;
private final DataSource.Factory dataSourceFactory; private final DataSource.Factory dataSourceFactory;
private final SmoothStreamingChunkSource.Factory chunkSourceFactory; private final SsChunkSource.Factory chunkSourceFactory;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final SmoothStreamingManifestParser manifestParser; private final SsManifestParser manifestParser;
private DataSource manifestDataSource; private DataSource manifestDataSource;
private Loader manifestLoader; private Loader manifestLoader;
private ChunkSampleStream<SmoothStreamingChunkSource>[] sampleStreams; private ChunkSampleStream<SsChunkSource>[] sampleStreams;
private CompositeSequenceableLoader sequenceableLoader; private CompositeSequenceableLoader sequenceableLoader;
private long manifestLoadStartTimestamp; private long manifestLoadStartTimestamp;
private SmoothStreamingManifest manifest; private SsManifest manifest;
private Callback callback; private Callback callback;
private Allocator allocator; private Allocator allocator;
@ -87,15 +89,15 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
private TrackGroupArray trackGroups; private TrackGroupArray trackGroups;
private int[] trackGroupElementIndices; private int[] trackGroupElementIndices;
public SmoothStreamingMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory, public SsMediaSource(Uri manifestUri, DataSource.Factory manifestDataSourceFactory,
SmoothStreamingChunkSource.Factory chunkSourceFactory, Handler eventHandler, SsChunkSource.Factory chunkSourceFactory, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) { AdaptiveMediaSourceEventListener eventListener) {
this(manifestUri, manifestDataSourceFactory, chunkSourceFactory, this(manifestUri, manifestDataSourceFactory, chunkSourceFactory,
DEFAULT_MIN_LOADABLE_RETRY_COUNT, eventHandler, eventListener); DEFAULT_MIN_LOADABLE_RETRY_COUNT, eventHandler, eventListener);
} }
public SmoothStreamingMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory, public SsMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
SmoothStreamingChunkSource.Factory chunkSourceFactory, int minLoadableRetryCount, SsChunkSource.Factory chunkSourceFactory, int minLoadableRetryCount,
Handler eventHandler, AdaptiveMediaSourceEventListener eventListener) { Handler eventHandler, AdaptiveMediaSourceEventListener eventListener) {
this.manifestUri = Util.toLowerInvariant(manifestUri.getLastPathSegment()).equals("manifest") this.manifestUri = Util.toLowerInvariant(manifestUri.getLastPathSegment()).equals("manifest")
? manifestUri : Uri.withAppendedPath(manifestUri, "Manifest"); ? manifestUri : Uri.withAppendedPath(manifestUri, "Manifest");
@ -103,7 +105,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
this.chunkSourceFactory = chunkSourceFactory; this.chunkSourceFactory = chunkSourceFactory;
this.minLoadableRetryCount = minLoadableRetryCount; this.minLoadableRetryCount = minLoadableRetryCount;
this.eventDispatcher = new EventDispatcher(eventHandler, eventListener); this.eventDispatcher = new EventDispatcher(eventHandler, eventListener);
manifestParser = new SmoothStreamingManifestParser(); manifestParser = new SsManifestParser();
} }
// MediaSource implementation. // MediaSource implementation.
@ -162,12 +164,12 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
public SampleStream[] selectTracks(List<SampleStream> oldStreams, public SampleStream[] selectTracks(List<SampleStream> oldStreams,
List<TrackSelection> newSelections, long positionUs) { List<TrackSelection> newSelections, long positionUs) {
int newEnabledSourceCount = sampleStreams.length + newSelections.size() - oldStreams.size(); int newEnabledSourceCount = sampleStreams.length + newSelections.size() - oldStreams.size();
ChunkSampleStream<SmoothStreamingChunkSource>[] newSampleStreams = ChunkSampleStream<SsChunkSource>[] newSampleStreams =
newSampleStreamArray(newEnabledSourceCount); newSampleStreamArray(newEnabledSourceCount);
int newEnabledSourceIndex = 0; int newEnabledSourceIndex = 0;
// Iterate over currently enabled streams, either releasing them or adding them to the new list. // Iterate over currently enabled streams, either releasing them or adding them to the new list.
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) { for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
if (oldStreams.contains(sampleStream)) { if (oldStreams.contains(sampleStream)) {
sampleStream.release(); sampleStream.release();
} else { } else {
@ -206,7 +208,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
@Override @Override
public long getBufferedPositionUs() { public long getBufferedPositionUs() {
long bufferedPositionUs = Long.MAX_VALUE; long bufferedPositionUs = Long.MAX_VALUE;
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) { for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
long rendererBufferedPositionUs = sampleStream.getBufferedPositionUs(); long rendererBufferedPositionUs = sampleStream.getBufferedPositionUs();
if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) { if (rendererBufferedPositionUs != C.END_OF_SOURCE_US) {
bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs); bufferedPositionUs = Math.min(bufferedPositionUs, rendererBufferedPositionUs);
@ -217,7 +219,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
@Override @Override
public long seekToUs(long positionUs) { public long seekToUs(long positionUs) {
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) { for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
sampleStream.seekToUs(positionUs); sampleStream.seekToUs(positionUs);
} }
return positionUs; return positionUs;
@ -231,7 +233,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
manifestLoader = null; manifestLoader = null;
} }
if (sampleStreams != null) { if (sampleStreams != null) {
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) { for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
sampleStream.release(); sampleStream.release();
} }
sampleStreams = null; sampleStreams = null;
@ -256,15 +258,15 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
@Override @Override
public void onContinueLoadingRequested( public void onContinueLoadingRequested(
ChunkSampleStream<SmoothStreamingChunkSource> sampleStream) { ChunkSampleStream<SsChunkSource> sampleStream) {
callback.onContinueLoadingRequested(this); callback.onContinueLoadingRequested(this);
} }
// Loader.Callback implementation // Loader.Callback implementation
@Override @Override
public void onLoadCompleted(ParsingLoadable<SmoothStreamingManifest> loadable, public void onLoadCompleted(ParsingLoadable<SsManifest> loadable, long elapsedRealtimeMs,
long elapsedRealtimeMs, long loadDurationMs) { long loadDurationMs) {
eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, elapsedRealtimeMs, eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, elapsedRealtimeMs,
loadDurationMs, loadable.bytesLoaded()); loadDurationMs, loadable.bytesLoaded());
manifest = loadable.getResult(); manifest = loadable.getResult();
@ -281,7 +283,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
prepared = true; prepared = true;
callback.onPeriodPrepared(this); callback.onPeriodPrepared(this);
} else { } else {
for (ChunkSampleStream<SmoothStreamingChunkSource> sampleStream : sampleStreams) { for (ChunkSampleStream<SsChunkSource> sampleStream : sampleStreams) {
sampleStream.getChunkSource().updateManifest(manifest); sampleStream.getChunkSource().updateManifest(manifest);
} }
callback.onContinueLoadingRequested(this); callback.onContinueLoadingRequested(this);
@ -290,14 +292,14 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
} }
@Override @Override
public void onLoadCanceled(ParsingLoadable<SmoothStreamingManifest> loadable, public void onLoadCanceled(ParsingLoadable<SsManifest> loadable, long elapsedRealtimeMs,
long elapsedRealtimeMs, long loadDurationMs, boolean released) { long loadDurationMs, boolean released) {
eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, elapsedRealtimeMs, eventDispatcher.loadCompleted(loadable.dataSpec, loadable.type, elapsedRealtimeMs,
loadDurationMs, loadable.bytesLoaded()); loadDurationMs, loadable.bytesLoaded());
} }
@Override @Override
public int onLoadError(ParsingLoadable<SmoothStreamingManifest> loadable, long elapsedRealtimeMs, public int onLoadError(ParsingLoadable<SsManifest> loadable, long elapsedRealtimeMs,
long loadDurationMs, IOException error) { long loadDurationMs, IOException error) {
boolean isFatal = error instanceof ParserException; boolean isFatal = error instanceof ParserException;
eventDispatcher.loadError(loadable.dataSpec, loadable.type, elapsedRealtimeMs, loadDurationMs, eventDispatcher.loadError(loadable.dataSpec, loadable.type, elapsedRealtimeMs, loadDurationMs,
@ -322,13 +324,13 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
} }
private void startLoadingManifest() { private void startLoadingManifest() {
ParsingLoadable<SmoothStreamingManifest> loadable = new ParsingLoadable<>(manifestDataSource, ParsingLoadable<SsManifest> loadable = new ParsingLoadable<>(manifestDataSource,
manifestUri, C.DATA_TYPE_MANIFEST, manifestParser); manifestUri, C.DATA_TYPE_MANIFEST, manifestParser);
long elapsedRealtimeMs = manifestLoader.startLoading(loadable, this, minLoadableRetryCount); long elapsedRealtimeMs = manifestLoader.startLoading(loadable, this, minLoadableRetryCount);
eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs); eventDispatcher.loadStarted(loadable.dataSpec, loadable.type, elapsedRealtimeMs);
} }
private void buildTrackGroups(SmoothStreamingManifest manifest) { private void buildTrackGroups(SsManifest manifest) {
int trackGroupCount = 0; int trackGroupCount = 0;
trackGroupElementIndices = new int[manifest.streamElements.length]; trackGroupElementIndices = new int[manifest.streamElements.length];
TrackGroup[] trackGroupArray = new TrackGroup[manifest.streamElements.length]; TrackGroup[] trackGroupArray = new TrackGroup[manifest.streamElements.length];
@ -350,11 +352,11 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
trackGroups = new TrackGroupArray(trackGroupArray); trackGroups = new TrackGroupArray(trackGroupArray);
} }
private ChunkSampleStream<SmoothStreamingChunkSource> buildSampleStream(TrackSelection selection, private ChunkSampleStream<SsChunkSource> buildSampleStream(TrackSelection selection,
long positionUs) { long positionUs) {
int[] selectedTracks = selection.getTracks(); int[] selectedTracks = selection.getTracks();
int streamElementIndex = trackGroupElementIndices[selection.group]; int streamElementIndex = trackGroupElementIndices[selection.group];
SmoothStreamingChunkSource chunkSource = chunkSourceFactory.createChunkSource(manifestLoader, SsChunkSource chunkSource = chunkSourceFactory.createChunkSource(manifestLoader,
manifest, streamElementIndex, trackGroups.get(selection.group), selectedTracks, manifest, streamElementIndex, trackGroups.get(selection.group), selectedTracks,
trackEncryptionBoxes); trackEncryptionBoxes);
return new ChunkSampleStream<>(manifest.streamElements[streamElementIndex].type, chunkSource, return new ChunkSampleStream<>(manifest.streamElements[streamElementIndex].type, chunkSource,
@ -362,7 +364,7 @@ public final class SmoothStreamingMediaSource implements MediaPeriod, MediaSourc
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static ChunkSampleStream<SmoothStreamingChunkSource>[] newSampleStreamArray(int length) { private static ChunkSampleStream<SsChunkSource>[] newSampleStreamArray(int length) {
return new ChunkSampleStream[length]; return new ChunkSampleStream[length];
} }

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.smoothstreaming; package com.google.android.exoplayer2.source.smoothstreaming.manifest;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
@ -32,7 +32,7 @@ import java.util.UUID;
* @see <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx"> * @see <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">
* IIS Smooth Streaming Client Manifest Format</a> * IIS Smooth Streaming Client Manifest Format</a>
*/ */
public class SmoothStreamingManifest { public class SsManifest {
/** /**
* The client manifest major version. * The client manifest major version.
@ -92,7 +92,7 @@ public class SmoothStreamingManifest {
* protected. * protected.
* @param streamElements The contained stream elements. * @param streamElements The contained stream elements.
*/ */
public SmoothStreamingManifest(int majorVersion, int minorVersion, long timescale, long duration, public SsManifest(int majorVersion, int minorVersion, long timescale, long duration,
long dvrWindowLength, int lookAheadCount, boolean isLive, ProtectionElement protectionElement, long dvrWindowLength, int lookAheadCount, boolean isLive, ProtectionElement protectionElement,
StreamElement[] streamElements) { StreamElement[] streamElements) {
this.majorVersion = majorVersion; this.majorVersion = majorVersion;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.android.exoplayer2.source.smoothstreaming; package com.google.android.exoplayer2.source.smoothstreaming.manifest;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
@ -21,8 +21,8 @@ import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData; import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil; import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingManifest.ProtectionElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.ProtectionElement;
import com.google.android.exoplayer2.source.smoothstreaming.SmoothStreamingManifest.StreamElement; import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
import com.google.android.exoplayer2.upstream.ParsingLoadable; import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.CodecSpecificDataUtil; import com.google.android.exoplayer2.util.CodecSpecificDataUtil;
@ -52,12 +52,11 @@ import java.util.UUID;
* @see <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx"> * @see <a href="http://msdn.microsoft.com/en-us/library/ee673436(v=vs.90).aspx">
* IIS Smooth Streaming Client Manifest Format</a> * IIS Smooth Streaming Client Manifest Format</a>
*/ */
public class SmoothStreamingManifestParser implements public class SsManifestParser implements ParsingLoadable.Parser<SsManifest> {
ParsingLoadable.Parser<SmoothStreamingManifest> {
private final XmlPullParserFactory xmlParserFactory; private final XmlPullParserFactory xmlParserFactory;
public SmoothStreamingManifestParser() { public SsManifestParser() {
try { try {
xmlParserFactory = XmlPullParserFactory.newInstance(); xmlParserFactory = XmlPullParserFactory.newInstance();
} catch (XmlPullParserException e) { } catch (XmlPullParserException e) {
@ -66,13 +65,13 @@ public class SmoothStreamingManifestParser implements
} }
@Override @Override
public SmoothStreamingManifest parse(Uri uri, InputStream inputStream) throws IOException { public SsManifest parse(Uri uri, InputStream inputStream) throws IOException {
try { try {
XmlPullParser xmlParser = xmlParserFactory.newPullParser(); XmlPullParser xmlParser = xmlParserFactory.newPullParser();
xmlParser.setInput(inputStream, null); xmlParser.setInput(inputStream, null);
SmoothStreamMediaParser smoothStreamMediaParser = SmoothStreamingMediaParser smoothStreamingMediaParser =
new SmoothStreamMediaParser(null, uri.toString()); new SmoothStreamingMediaParser(null, uri.toString());
return (SmoothStreamingManifest) smoothStreamMediaParser.parse(xmlParser); return (SsManifest) smoothStreamingMediaParser.parse(xmlParser);
} catch (XmlPullParserException e) { } catch (XmlPullParserException e) {
throw new ParserException(e); throw new ParserException(e);
} }
@ -163,12 +162,12 @@ public class SmoothStreamingManifestParser implements
} }
private ElementParser newChildParser(ElementParser parent, String name, String baseUri) { private ElementParser newChildParser(ElementParser parent, String name, String baseUri) {
if (TrackElementParser.TAG.equals(name)) { if (QualityLevelParser.TAG.equals(name)) {
return new TrackElementParser(parent, baseUri); return new QualityLevelParser(parent, baseUri);
} else if (ProtectionElementParser.TAG.equals(name)) { } else if (ProtectionParser.TAG.equals(name)) {
return new ProtectionElementParser(parent, baseUri); return new ProtectionParser(parent, baseUri);
} else if (StreamElementParser.TAG.equals(name)) { } else if (StreamIndexParser.TAG.equals(name)) {
return new StreamElementParser(parent, baseUri); return new StreamIndexParser(parent, baseUri);
} }
return null; return null;
} }
@ -322,7 +321,7 @@ public class SmoothStreamingManifestParser implements
} }
private static class SmoothStreamMediaParser extends ElementParser { private static class SmoothStreamingMediaParser extends ElementParser {
public static final String TAG = "SmoothStreamingMedia"; public static final String TAG = "SmoothStreamingMedia";
@ -345,7 +344,7 @@ public class SmoothStreamingManifestParser implements
private boolean isLive; private boolean isLive;
private ProtectionElement protectionElement; private ProtectionElement protectionElement;
public SmoothStreamMediaParser(ElementParser parent, String baseUri) { public SmoothStreamingMediaParser(ElementParser parent, String baseUri) {
super(parent, baseUri, TAG); super(parent, baseUri, TAG);
lookAheadCount = -1; lookAheadCount = -1;
protectionElement = null; protectionElement = null;
@ -387,13 +386,13 @@ public class SmoothStreamingManifestParser implements
} }
} }
} }
return new SmoothStreamingManifest(majorVersion, minorVersion, timescale, duration, return new SsManifest(majorVersion, minorVersion, timescale, duration, dvrWindowLength,
dvrWindowLength, lookAheadCount, isLive, protectionElement, streamElementArray); lookAheadCount, isLive, protectionElement, streamElementArray);
} }
} }
private static class ProtectionElementParser extends ElementParser { private static class ProtectionParser extends ElementParser {
public static final String TAG = "Protection"; public static final String TAG = "Protection";
public static final String TAG_PROTECTION_HEADER = "ProtectionHeader"; public static final String TAG_PROTECTION_HEADER = "ProtectionHeader";
@ -404,7 +403,7 @@ public class SmoothStreamingManifestParser implements
private UUID uuid; private UUID uuid;
private byte[] initData; private byte[] initData;
public ProtectionElementParser(ElementParser parent, String baseUri) { public ProtectionParser(ElementParser parent, String baseUri) {
super(parent, baseUri, TAG); super(parent, baseUri, TAG);
} }
@ -450,7 +449,7 @@ public class SmoothStreamingManifestParser implements
} }
} }
private static class StreamElementParser extends ElementParser { private static class StreamIndexParser extends ElementParser {
public static final String TAG = "StreamIndex"; public static final String TAG = "StreamIndex";
private static final String TAG_STREAM_FRAGMENT = "c"; private static final String TAG_STREAM_FRAGMENT = "c";
@ -492,7 +491,7 @@ public class SmoothStreamingManifestParser implements
private long lastChunkDuration; private long lastChunkDuration;
public StreamElementParser(ElementParser parent, String baseUri) { public StreamIndexParser(ElementParser parent, String baseUri) {
super(parent, baseUri, TAG); super(parent, baseUri, TAG);
this.baseUri = baseUri; this.baseUri = baseUri;
formats = new LinkedList<>(); formats = new LinkedList<>();
@ -599,7 +598,7 @@ public class SmoothStreamingManifestParser implements
} }
private static class TrackElementParser extends ElementParser { private static class QualityLevelParser extends ElementParser {
public static final String TAG = "QualityLevel"; public static final String TAG = "QualityLevel";
@ -616,7 +615,7 @@ public class SmoothStreamingManifestParser implements
private Format format; private Format format;
public TrackElementParser(ElementParser parent, String baseUri) { public QualityLevelParser(ElementParser parent, String baseUri) {
super(parent, baseUri, TAG); super(parent, baseUri, TAG);
} }

View File

@ -180,8 +180,12 @@ public class TestUtil {
public static byte[] getByteArray(Instrumentation instrumentation, String fileName) public static byte[] getByteArray(Instrumentation instrumentation, String fileName)
throws IOException { throws IOException {
InputStream is = instrumentation.getContext().getResources().getAssets().open(fileName); return Util.toByteArray(getInputStream(instrumentation, fileName));
return Util.toByteArray(is); }
public static InputStream getInputStream(Instrumentation instrumentation, String fileName)
throws IOException {
return instrumentation.getContext().getResources().getAssets().open(fileName);
} }
public static String getString(Instrumentation instrumentation, String fileName) public static String getString(Instrumentation instrumentation, String fileName)