Skip to content

Commit

Permalink
Use AVERAGE-BANDWIDTH instead of BANDWIDTH when available
Browse files Browse the repository at this point in the history
Also prevent BANDWIDTH's regex from matching the AVERAGE-BANDWIDTH attribute.

Issue:#2863

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=157219453
  • Loading branch information
AquilesCanta authored and ojw28 committed Jun 6, 2017
1 parent 5a754fe commit 2795269
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ public class HlsMasterPlaylistParserTest extends TestCase {
+ "#EXT-X-STREAM-INF:BANDWIDTH=65000,CODECS=\"mp4a.40.5\"\n"
+ "http://example.com/audio-only.m3u8";

private static final String AVG_BANDWIDTH_MASTER_PLAYLIST = " #EXTM3U \n"
+ "\n"
+ "#EXT-X-STREAM-INF:BANDWIDTH=1280000,CODECS=\"mp4a.40.2,avc1.66.30\",RESOLUTION=304x128\n"
+ "http://example.com/low.m3u8\n"
+ "\n"
+ "#EXT-X-STREAM-INF:BANDWIDTH=1280000,AVERAGE-BANDWIDTH=1270000,"
+ "CODECS=\"mp4a.40.2 , avc1.66.30 \"\n"
+ "http://example.com/spaces_in_codecs.m3u8\n";

private static final String PLAYLIST_WITH_INVALID_HEADER = "#EXTMU3\n"
+ "#EXT-X-STREAM-INF:BANDWIDTH=1280000,CODECS=\"mp4a.40.2,avc1.66.30\",RESOLUTION=304x128\n"
+ "http://example.com/low.m3u8\n";
Expand All @@ -70,42 +79,48 @@ public void testParseMasterPlaylist() throws IOException{
HlsMasterPlaylist masterPlaylist = parseMasterPlaylist(PLAYLIST_URI, MASTER_PLAYLIST);

List<HlsMasterPlaylist.HlsUrl> variants = masterPlaylist.variants;
assertNotNull(variants);
assertEquals(5, variants.size());
assertNull(masterPlaylist.muxedCaptionFormats);

assertEquals(1280000, variants.get(0).format.bitrate);
assertNotNull(variants.get(0).format.codecs);
assertEquals("mp4a.40.2,avc1.66.30", variants.get(0).format.codecs);
assertEquals(304, variants.get(0).format.width);
assertEquals(128, variants.get(0).format.height);
assertEquals("http://example.com/low.m3u8", variants.get(0).url);

assertEquals(1280000, variants.get(1).format.bitrate);
assertNotNull(variants.get(1).format.codecs);
assertEquals("mp4a.40.2 , avc1.66.30 ", variants.get(1).format.codecs);
assertEquals("http://example.com/spaces_in_codecs.m3u8", variants.get(1).url);

assertEquals(2560000, variants.get(2).format.bitrate);
assertEquals(null, variants.get(2).format.codecs);
assertNull(variants.get(2).format.codecs);
assertEquals(384, variants.get(2).format.width);
assertEquals(160, variants.get(2).format.height);
assertEquals("http://example.com/mid.m3u8", variants.get(2).url);

assertEquals(7680000, variants.get(3).format.bitrate);
assertEquals(null, variants.get(3).format.codecs);
assertNull(variants.get(3).format.codecs);
assertEquals(Format.NO_VALUE, variants.get(3).format.width);
assertEquals(Format.NO_VALUE, variants.get(3).format.height);
assertEquals("http://example.com/hi.m3u8", variants.get(3).url);

assertEquals(65000, variants.get(4).format.bitrate);
assertNotNull(variants.get(4).format.codecs);
assertEquals("mp4a.40.5", variants.get(4).format.codecs);
assertEquals(Format.NO_VALUE, variants.get(4).format.width);
assertEquals(Format.NO_VALUE, variants.get(4).format.height);
assertEquals("http://example.com/audio-only.m3u8", variants.get(4).url);
}

public void testMasterPlaylistWithBandwdithAverage() throws IOException {
HlsMasterPlaylist masterPlaylist = parseMasterPlaylist(PLAYLIST_URI,
AVG_BANDWIDTH_MASTER_PLAYLIST);

List<HlsMasterPlaylist.HlsUrl> variants = masterPlaylist.variants;

assertEquals(1280000, variants.get(0).format.bitrate);
assertEquals(1270000, variants.get(1).format.bitrate);
}

public void testPlaylistWithInvalidHeader() throws IOException {
try {
parseMasterPlaylist(PLAYLIST_URI, PLAYLIST_WITH_INVALID_HEADER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli

private static final String ATTR_CLOSED_CAPTIONS_NONE = "CLOSED-CAPTIONS=NONE";

private static final Pattern REGEX_BANDWIDTH = Pattern.compile("BANDWIDTH=(\\d+)\\b");
private static final Pattern REGEX_AVERAGE_BANDWIDTH =
Pattern.compile("AVERAGE-BANDWIDTH=(\\d+)\\b");
private static final Pattern REGEX_BANDWIDTH = Pattern.compile("[^-]BANDWIDTH=(\\d+)\\b");
private static final Pattern REGEX_CODECS = Pattern.compile("CODECS=\"(.+?)\"");
private static final Pattern REGEX_RESOLUTION = Pattern.compile("RESOLUTION=(\\d+x\\d+)");
private static final Pattern REGEX_TARGET_DURATION = Pattern.compile(TAG_TARGET_DURATION
Expand Down Expand Up @@ -226,6 +228,11 @@ private static HlsMasterPlaylist parseMasterPlaylist(LineIterator iterator, Stri
}
} else if (line.startsWith(TAG_STREAM_INF)) {
int bitrate = parseIntAttr(line, REGEX_BANDWIDTH);
String averageBandwidthString = parseOptionalStringAttr(line, REGEX_AVERAGE_BANDWIDTH);
if (averageBandwidthString != null) {
// If available, the average bandwidth attribute is used as the variant's bitrate.
bitrate = Integer.parseInt(averageBandwidthString);
}
String codecs = parseOptionalStringAttr(line, REGEX_CODECS);
String resolutionString = parseOptionalStringAttr(line, REGEX_RESOLUTION);
noClosedCaptions |= line.contains(ATTR_CLOSED_CAPTIONS_NONE);
Expand Down Expand Up @@ -390,14 +397,6 @@ private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String
dateRanges);
}

private static String parseStringAttr(String line, Pattern pattern) throws ParserException {
Matcher matcher = pattern.matcher(line);
if (matcher.find() && matcher.groupCount() == 1) {
return matcher.group(1);
}
throw new ParserException("Couldn't match " + pattern.pattern() + " in " + line);
}

private static int parseIntAttr(String line, Pattern pattern) throws ParserException {
return Integer.parseInt(parseStringAttr(line, pattern));
}
Expand All @@ -408,10 +407,15 @@ private static double parseDoubleAttr(String line, Pattern pattern) throws Parse

private static String parseOptionalStringAttr(String line, Pattern pattern) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
return matcher.find() ? matcher.group(1) : null;
}

private static String parseStringAttr(String line, Pattern pattern) throws ParserException {
Matcher matcher = pattern.matcher(line);
if (matcher.find() && matcher.groupCount() == 1) {
return matcher.group(1);
}
return null;
throw new ParserException("Couldn't match " + pattern.pattern() + " in " + line);
}

private static boolean parseBooleanAttribute(String line, Pattern pattern, boolean defaultValue) {
Expand Down

0 comments on commit 2795269

Please sign in to comment.