com.google.android.exoplayer2.ParserException Java Examples

The following examples show how to use com.google.android.exoplayer2.ParserException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AdtsReader.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
@Override
public void consume(ParsableByteArray data) throws ParserException {
  while (data.bytesLeft() > 0) {
    switch (state) {
      case STATE_FINDING_SAMPLE:
        findNextSample(data);
        break;
      case STATE_READING_ID3_HEADER:
        if (continueRead(data, id3HeaderBuffer.data, ID3_HEADER_SIZE)) {
          parseId3Header();
        }
        break;
      case STATE_READING_ADTS_HEADER:
        int targetLength = hasCrc ? HEADER_SIZE + CRC_SIZE : HEADER_SIZE;
        if (continueRead(data, adtsScratch.data, targetLength)) {
          parseAdtsHeader();
        }
        break;
      case STATE_READING_SAMPLE:
        readSample(data);
        break;
    }
  }
}
 
Example #2
Source File: FragmentedMp4Extractor.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
/**
 * Parses a saio atom (defined in 14496-12).
 *
 * @param saio The saio atom to decode.
 * @param out The {@link TrackFragment} to populate with data from the saio atom.
 */
private static void parseSaio(ParsableByteArray saio, TrackFragment out) throws ParserException {
  saio.setPosition(Atom.HEADER_SIZE);
  int fullAtom = saio.readInt();
  int flags = Atom.parseFullAtomFlags(fullAtom);
  if ((flags & 0x01) == 1) {
    saio.skipBytes(8);
  }

  int entryCount = saio.readUnsignedIntToInt();
  if (entryCount != 1) {
    // We only support one trun element currently, so always expect one entry.
    throw new ParserException("Unexpected saio entry count: " + entryCount);
  }

  int version = Atom.parseFullAtomVersion(fullAtom);
  out.auxiliaryDataPosition +=
      version == 0 ? saio.readUnsignedInt() : saio.readUnsignedLongToLong();
}
 
Example #3
Source File: MatroskaExtractor.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Parses an MS/ACM codec private, returning whether it indicates PCM audio.
 *
 * @return Whether the codec private indicates PCM audio.
 * @throws ParserException If a parsing error occurs.
 */
private static boolean parseMsAcmCodecPrivate(ParsableByteArray buffer) throws ParserException {
  try {
    int formatTag = buffer.readLittleEndianUnsignedShort();
    if (formatTag == WAVE_FORMAT_PCM) {
      return true;
    } else if (formatTag == WAVE_FORMAT_EXTENSIBLE) {
      buffer.setPosition(WAVE_FORMAT_SIZE + 6); // unionSamples(2), channelMask(4)
      return buffer.readLong() == WAVE_SUBFORMAT_PCM.getMostSignificantBits()
          && buffer.readLong() == WAVE_SUBFORMAT_PCM.getLeastSignificantBits();
    } else {
      return false;
    }
  } catch (ArrayIndexOutOfBoundsException e) {
    throw new ParserException("Error parsing MS/ACM codec private");
  }
}
 
Example #4
Source File: DashMediaSource.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
LoadErrorAction onManifestLoadError(
    ParsingLoadable<DashManifest> loadable,
    long elapsedRealtimeMs,
    long loadDurationMs,
    IOException error) {
  boolean isFatal = error instanceof ParserException;
  manifestEventDispatcher.loadError(
      loadable.dataSpec,
      loadable.getUri(),
      loadable.type,
      elapsedRealtimeMs,
      loadDurationMs,
      loadable.bytesLoaded(),
      error,
      isFatal);
  return isFatal ? Loader.DONT_RETRY_FATAL : Loader.RETRY;
}
 
Example #5
Source File: MatroskaExtractor.java    From TelePlus-Android with GNU General Public License v2.0 6 votes vote down vote up
void stringElement(int id, String value) throws ParserException {
  switch (id) {
    case ID_DOC_TYPE:
      // Validate that DocType is supported.
      if (!DOC_TYPE_WEBM.equals(value) && !DOC_TYPE_MATROSKA.equals(value)) {
        throw new ParserException("DocType " + value + " not supported");
      }
      break;
    case ID_CODEC_ID:
      currentTrack.codecId = value;
      break;
    case ID_LANGUAGE:
      currentTrack.language = value;
      break;
    default:
      break;
  }
}
 
Example #6
Source File: RawCcExtractor.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
private boolean parseTimestampAndSampleCount(ExtractorInput input) throws IOException,
    InterruptedException {
  dataScratch.reset();
  if (version == 0) {
    if (!input.readFully(dataScratch.data, 0, TIMESTAMP_SIZE_V0 + 1, true)) {
      return false;
    }
    // version 0 timestamps are 45kHz, so we need to convert them into us
    timestampUs = dataScratch.readUnsignedInt() * 1000 / 45;
  } else if (version == 1) {
    if (!input.readFully(dataScratch.data, 0, TIMESTAMP_SIZE_V1 + 1, true)) {
      return false;
    }
    timestampUs = dataScratch.readLong();
  } else {
    throw new ParserException("Unsupported version number: " + version);
  }

  remainingSampleCount = dataScratch.readUnsignedByte();
  sampleBytesWritten = 0;
  return true;
}
 
Example #7
Source File: DefaultHlsPlaylistTracker.java    From MediaSDK with Apache License 2.0 6 votes vote down vote up
@Override
public void onLoadCompleted(
    ParsingLoadable<HlsPlaylist> loadable, long elapsedRealtimeMs, long loadDurationMs) {
  HlsPlaylist result = loadable.getResult();
  if (result instanceof HlsMediaPlaylist) {
    processLoadedPlaylist((HlsMediaPlaylist) result, loadDurationMs);
    eventDispatcher.loadCompleted(
        loadable.dataSpec,
        loadable.getUri(),
        loadable.getResponseHeaders(),
        C.DATA_TYPE_MANIFEST,
        elapsedRealtimeMs,
        loadDurationMs,
        loadable.bytesLoaded());
  } else {
    playlistError = new ParserException("Loaded playlist has unexpected type.");
  }
}
 
Example #8
Source File: LatmReader.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private int parsePayloadLengthInfo(ParsableBitArray data) throws ParserException {
  int muxSlotLengthBytes = 0;
  // Assuming single program and single layer.
  if (frameLengthType == 0) {
    int tmp;
    do {
      tmp = data.readBits(8);
      muxSlotLengthBytes += tmp;
    } while (tmp == 255);
    return muxSlotLengthBytes;
  } else {
    throw new ParserException();
  }
}
 
Example #9
Source File: AtomParsers.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a stsd atom (defined in 14496-12).
 *
 * @param stsd The stsd atom to decode.
 * @param trackId The track's identifier in its container.
 * @param rotationDegrees The rotation of the track in degrees.
 * @param language The language of the track.
 * @param drmInitData {@link DrmInitData} to be included in the format.
 * @param isQuickTime True for QuickTime media. False otherwise.
 * @return An object containing the parsed data.
 */
private static StsdData parseStsd(ParsableByteArray stsd, int trackId, int rotationDegrees,
    String language, DrmInitData drmInitData, boolean isQuickTime) throws ParserException {
  stsd.setPosition(Atom.FULL_HEADER_SIZE);
  int numberOfEntries = stsd.readInt();
  StsdData out = new StsdData(numberOfEntries);
  for (int i = 0; i < numberOfEntries; i++) {
    int childStartPosition = stsd.getPosition();
    int childAtomSize = stsd.readInt();
    Assertions.checkArgument(childAtomSize > 0, "childAtomSize should be positive");
    int childAtomType = stsd.readInt();
    if (childAtomType == Atom.TYPE_avc1 || childAtomType == Atom.TYPE_avc3
        || childAtomType == Atom.TYPE_encv || childAtomType == Atom.TYPE_mp4v
        || childAtomType == Atom.TYPE_hvc1 || childAtomType == Atom.TYPE_hev1
        || childAtomType == Atom.TYPE_s263 || childAtomType == Atom.TYPE_vp08
        || childAtomType == Atom.TYPE_vp09) {
      parseVideoSampleEntry(stsd, childAtomType, childStartPosition, childAtomSize, trackId,
          rotationDegrees, drmInitData, out, i);
    } else if (childAtomType == Atom.TYPE_mp4a || childAtomType == Atom.TYPE_enca
        || childAtomType == Atom.TYPE_ac_3 || childAtomType == Atom.TYPE_ec_3
        || childAtomType == Atom.TYPE_dtsc || childAtomType == Atom.TYPE_dtse
        || childAtomType == Atom.TYPE_dtsh || childAtomType == Atom.TYPE_dtsl
        || childAtomType == Atom.TYPE_samr || childAtomType == Atom.TYPE_sawb
        || childAtomType == Atom.TYPE_lpcm || childAtomType == Atom.TYPE_sowt
        || childAtomType == Atom.TYPE__mp3 || childAtomType == Atom.TYPE_alac) {
      parseAudioSampleEntry(stsd, childAtomType, childStartPosition, childAtomSize, trackId,
          language, isQuickTime, drmInitData, out, i);
    } else if (childAtomType == Atom.TYPE_TTML || childAtomType == Atom.TYPE_tx3g
        || childAtomType == Atom.TYPE_wvtt || childAtomType == Atom.TYPE_stpp
        || childAtomType == Atom.TYPE_c608) {
      parseTextSampleEntry(stsd, childAtomType, childStartPosition, childAtomSize, trackId,
          language, out);
    } else if (childAtomType == Atom.TYPE_camm) {
      out.format = Format.createSampleFormat(Integer.toString(trackId),
          MimeTypes.APPLICATION_CAMERA_MOTION, null, Format.NO_VALUE, null);
    }
    stsd.setPosition(childStartPosition + childAtomSize);
  }
  return out;
}
 
Example #10
Source File: DashMediaSource.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
@Override
public Long parse(Uri uri, InputStream inputStream) throws IOException {
  String firstLine =
      new BufferedReader(new InputStreamReader(inputStream, Charset.forName(C.UTF8_NAME)))
          .readLine();
  try {
    Matcher matcher = TIMESTAMP_WITH_TIMEZONE_PATTERN.matcher(firstLine);
    if (!matcher.matches()) {
      throw new ParserException("Couldn't parse timestamp: " + firstLine);
    }
    // Parse the timestamp.
    String timestampWithoutTimezone = matcher.group(1);
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.US);
    format.setTimeZone(TimeZone.getTimeZone("UTC"));
    long timestampMs = format.parse(timestampWithoutTimezone).getTime();
    // Parse the timezone.
    String timezone = matcher.group(2);
    if ("Z".equals(timezone)) {
      // UTC (no offset).
    } else {
      long sign = "+".equals(matcher.group(4)) ? 1 : -1;
      long hours = Long.parseLong(matcher.group(5));
      String minutesString = matcher.group(7);
      long minutes = TextUtils.isEmpty(minutesString) ? 0 : Long.parseLong(minutesString);
      long timestampOffsetMs = sign * (((hours * 60) + minutes) * 60 * 1000);
      timestampMs -= timestampOffsetMs;
    }
    return timestampMs;
  } catch (ParseException e) {
    throw new ParserException(e);
  }
}
 
Example #11
Source File: HlsPlaylistParser.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private static String parseStringAttr(
    String line, Pattern pattern, Map<String, String> variableDefinitions)
    throws ParserException {
  String value = parseOptionalStringAttr(line, pattern, variableDefinitions);
  if (value != null) {
    return value;
  } else {
    throw new ParserException("Couldn't match " + pattern.pattern() + " in " + line);
  }
}
 
Example #12
Source File: VorbisUtil.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * This method reads the modes which are located at the very end of the vorbis setup header.
 * That's why we need to partially decode or at least read the entire setup header to know
 * where to start reading the modes.
 *
 * @see <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-650004.2.4">
 *     Vorbis spec/Setup header</a>
 * @param headerData a {@link ParsableByteArray} containing setup header data.
 * @param channels the number of channels.
 * @return an array of {@link Mode}s.
 * @throws ParserException thrown if bit stream is invalid.
 */
public static Mode[] readVorbisModes(ParsableByteArray headerData, int channels)
    throws ParserException {

  verifyVorbisHeaderCapturePattern(0x05, headerData, false);

  int numberOfBooks = headerData.readUnsignedByte() + 1;

  VorbisBitArray bitArray  = new VorbisBitArray(headerData.data);
  bitArray.skipBits(headerData.getPosition() * 8);

  for (int i = 0; i < numberOfBooks; i++) {
    readBook(bitArray);
  }

  int timeCount = bitArray.readBits(6) + 1;
  for (int i = 0; i < timeCount; i++) {
    if (bitArray.readBits(16) != 0x00) {
      throw new ParserException("placeholder of time domain transforms not zeroed out");
    }
  }
  readFloors(bitArray);
  readResidues(bitArray);
  readMappings(channels, bitArray);

  Mode[] modes = readModes(bitArray);
  if (!bitArray.readBit()) {
    throw new ParserException("framing bit after modes not set as expected");
  }
  return modes;
}
 
Example #13
Source File: VorbisUtil.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Verifies whether the next bytes in {@code header} are a vorbis header of the given
 * {@code headerType}.
 *
 * @param headerType the type of the header expected.
 * @param header the alleged header bytes.
 * @param quiet if {@code true} no exceptions are thrown. Instead {@code false} is returned.
 * @return the number of bytes read.
 * @throws ParserException thrown if header type or capture pattern is not as expected.
 */
public static boolean verifyVorbisHeaderCapturePattern(int headerType, ParsableByteArray header,
    boolean quiet)
    throws ParserException {
  if (header.bytesLeft() < 7) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("too short header: " + header.bytesLeft());
    }
  }

  if (header.readUnsignedByte() != headerType) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected header type " + Integer.toHexString(headerType));
    }
  }

  if (!(header.readUnsignedByte() == 'v'
      && header.readUnsignedByte() == 'o'
      && header.readUnsignedByte() == 'r'
      && header.readUnsignedByte() == 'b'
      && header.readUnsignedByte() == 'i'
      && header.readUnsignedByte() == 's')) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected characters 'vorbis'");
    }
  }
  return true;
}
 
Example #14
Source File: AvcConfig.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Parses AVC configuration data.
 *
 * @param data A {@link ParsableByteArray}, whose position is set to the start of the AVC
 *     configuration data to parse.
 * @return A parsed representation of the HEVC configuration data.
 * @throws ParserException If an error occurred parsing the data.
 */
public static AvcConfig parse(ParsableByteArray data) throws ParserException {
  try {
    data.skipBytes(4); // Skip to the AVCDecoderConfigurationRecord (defined in 14496-15)
    int nalUnitLengthFieldLength = (data.readUnsignedByte() & 0x3) + 1;
    if (nalUnitLengthFieldLength == 3) {
      throw new IllegalStateException();
    }
    List<byte[]> initializationData = new ArrayList<>();
    int numSequenceParameterSets = data.readUnsignedByte() & 0x1F;
    for (int j = 0; j < numSequenceParameterSets; j++) {
      initializationData.add(buildNalUnitForChild(data));
    }
    int numPictureParameterSets = data.readUnsignedByte();
    for (int j = 0; j < numPictureParameterSets; j++) {
      initializationData.add(buildNalUnitForChild(data));
    }

    int width = Format.NO_VALUE;
    int height = Format.NO_VALUE;
    float pixelWidthAspectRatio = 1;
    if (numSequenceParameterSets > 0) {
      byte[] sps = initializationData.get(0);
      SpsData spsData = NalUnitUtil.parseSpsNalUnit(initializationData.get(0),
          nalUnitLengthFieldLength, sps.length);
      width = spsData.width;
      height = spsData.height;
      pixelWidthAspectRatio = spsData.pixelWidthAspectRatio;
    }
    return new AvcConfig(initializationData, nalUnitLengthFieldLength, width, height,
        pixelWidthAspectRatio);
  } catch (ArrayIndexOutOfBoundsException e) {
    throw new ParserException("Error parsing AVC config", e);
  }
}
 
Example #15
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static void parseMoof(ContainerAtom moof, SparseArray<TrackBundle> trackBundleArray,
    @Flags int flags, byte[] extendedTypeScratch) throws ParserException {
  int moofContainerChildrenSize = moof.containerChildren.size();
  for (int i = 0; i < moofContainerChildrenSize; i++) {
    Atom.ContainerAtom child = moof.containerChildren.get(i);
    // TODO: Support multiple traf boxes per track in a single moof.
    if (child.type == Atom.TYPE_traf) {
      parseTraf(child, trackBundleArray, flags, extendedTypeScratch);
    }
  }
}
 
Example #16
Source File: VorbisUtil.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Verifies whether the next bytes in {@code header} are a vorbis header of the given
 * {@code headerType}.
 *
 * @param headerType the type of the header expected.
 * @param header the alleged header bytes.
 * @param quiet if {@code true} no exceptions are thrown. Instead {@code false} is returned.
 * @return the number of bytes read.
 * @throws ParserException thrown if header type or capture pattern is not as expected.
 */
public static boolean verifyVorbisHeaderCapturePattern(int headerType, ParsableByteArray header,
    boolean quiet)
    throws ParserException {
  if (header.bytesLeft() < 7) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("too short header: " + header.bytesLeft());
    }
  }

  if (header.readUnsignedByte() != headerType) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected header type " + Integer.toHexString(headerType));
    }
  }

  if (!(header.readUnsignedByte() == 'v'
      && header.readUnsignedByte() == 'o'
      && header.readUnsignedByte() == 'r'
      && header.readUnsignedByte() == 'b'
      && header.readUnsignedByte() == 'i'
      && header.readUnsignedByte() == 's')) {
    if (quiet) {
      return false;
    } else {
      throw new ParserException("expected characters 'vorbis'");
    }
  }
  return true;
}
 
Example #17
Source File: SsManifestParser.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
protected final int parseRequiredInt(XmlPullParser parser, String key) throws ParserException {
  String value = parser.getAttributeValue(null, key);
  if (value != null) {
    try {
      return Integer.parseInt(value);
    } catch (NumberFormatException e) {
      throw new ParserException(e);
    }
  } else {
    throw new MissingFieldException(key);
  }
}
 
Example #18
Source File: AvcConfig.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses AVC configuration data.
 *
 * @param data A {@link ParsableByteArray}, whose position is set to the start of the AVC
 *     configuration data to parse.
 * @return A parsed representation of the HEVC configuration data.
 * @throws ParserException If an error occurred parsing the data.
 */
public static AvcConfig parse(ParsableByteArray data) throws ParserException {
  try {
    data.skipBytes(4); // Skip to the AVCDecoderConfigurationRecord (defined in 14496-15)
    int nalUnitLengthFieldLength = (data.readUnsignedByte() & 0x3) + 1;
    if (nalUnitLengthFieldLength == 3) {
      throw new IllegalStateException();
    }
    List<byte[]> initializationData = new ArrayList<>();
    int numSequenceParameterSets = data.readUnsignedByte() & 0x1F;
    for (int j = 0; j < numSequenceParameterSets; j++) {
      initializationData.add(buildNalUnitForChild(data));
    }
    int numPictureParameterSets = data.readUnsignedByte();
    for (int j = 0; j < numPictureParameterSets; j++) {
      initializationData.add(buildNalUnitForChild(data));
    }

    int width = Format.NO_VALUE;
    int height = Format.NO_VALUE;
    float pixelWidthAspectRatio = 1;
    if (numSequenceParameterSets > 0) {
      byte[] sps = initializationData.get(0);
      SpsData spsData = NalUnitUtil.parseSpsNalUnit(initializationData.get(0),
          nalUnitLengthFieldLength, sps.length);
      width = spsData.width;
      height = spsData.height;
      pixelWidthAspectRatio = spsData.pixelWidthAspectRatio;
    }
    return new AvcConfig(initializationData, nalUnitLengthFieldLength, width, height,
        pixelWidthAspectRatio);
  } catch (ArrayIndexOutOfBoundsException e) {
    throw new ParserException("Error parsing AVC config", e);
  }
}
 
Example #19
Source File: FragmentedMp4Extractor.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private static void parseSaiz(TrackEncryptionBox encryptionBox, ParsableByteArray saiz,
    TrackFragment out) throws ParserException {
  int vectorSize = encryptionBox.perSampleIvSize;
  saiz.setPosition(Atom.HEADER_SIZE);
  int fullAtom = saiz.readInt();
  int flags = Atom.parseFullAtomFlags(fullAtom);
  if ((flags & 0x01) == 1) {
    saiz.skipBytes(8);
  }
  int defaultSampleInfoSize = saiz.readUnsignedByte();

  int sampleCount = saiz.readUnsignedIntToInt();
  if (sampleCount != out.sampleCount) {
    throw new ParserException("Length mismatch: " + sampleCount + ", " + out.sampleCount);
  }

  int totalSize = 0;
  if (defaultSampleInfoSize == 0) {
    boolean[] sampleHasSubsampleEncryptionTable = out.sampleHasSubsampleEncryptionTable;
    for (int i = 0; i < sampleCount; i++) {
      int sampleInfoSize = saiz.readUnsignedByte();
      totalSize += sampleInfoSize;
      sampleHasSubsampleEncryptionTable[i] = sampleInfoSize > vectorSize;
    }
  } else {
    boolean subsampleEncryption = defaultSampleInfoSize > vectorSize;
    totalSize += defaultSampleInfoSize * sampleCount;
    Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption);
  }
  out.initEncryptionData(totalSize);
}
 
Example #20
Source File: DashMediaSource.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
private void resolveUtcTimingElementDirect(UtcTimingElement timingElement) {
  try {
    long utcTimestampMs = Util.parseXsDateTime(timingElement.value);
    onUtcTimestampResolved(utcTimestampMs - manifestLoadEndTimestampMs);
  } catch (ParserException e) {
    onUtcTimestampResolutionError(e);
  }
}
 
Example #21
Source File: DashManifestParser.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
protected static long parseDateTime(XmlPullParser xpp, String name, long defaultValue)
    throws ParserException {
  String value = xpp.getAttributeValue(null, name);
  if (value == null) {
    return defaultValue;
  } else {
    return Util.parseXsDateTime(value);
  }
}
 
Example #22
Source File: FragmentedMp4Extractor.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private void onLeafAtomRead(LeafAtom leaf, long inputPosition) throws ParserException {
  if (!containerAtoms.isEmpty()) {
    containerAtoms.peek().add(leaf);
  } else if (leaf.type == Atom.TYPE_sidx) {
    Pair<Long, ChunkIndex> result = parseSidx(leaf.data, inputPosition);
    segmentIndexEarliestPresentationTimeUs = result.first;
    extractorOutput.seekMap(result.second);
    haveOutputSeekMap = true;
  } else if (leaf.type == Atom.TYPE_emsg) {
    onEmsgLeafAtomRead(leaf.data);
  }
}
 
Example #23
Source File: DashManifestParser.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
public DashManifest parse(Uri uri, InputStream inputStream) throws IOException {
  try {
    XmlPullParser xpp = xmlParserFactory.newPullParser();
    xpp.setInput(inputStream, null);
    int eventType = xpp.next();
    if (eventType != XmlPullParser.START_TAG || !"MPD".equals(xpp.getName())) {
      throw new ParserException(
          "inputStream does not contain a valid media presentation description");
    }
    return parseMediaPresentationDescription(xpp, uri.toString());
  } catch (XmlPullParserException e) {
    throw new ParserException(e);
  }
}
 
Example #24
Source File: MatroskaExtractor.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Builds initialization data for a {@link Format} from FourCC codec private data.
 *
 * @return The codec mime type and initialization data. If the compression type is not supported
 *     then the mime type is set to {@link MimeTypes#VIDEO_UNKNOWN} and the initialization data
 *     is {@code null}.
 * @throws ParserException If the initialization data could not be built.
 */
private static Pair<String, List<byte[]>> parseFourCcPrivate(ParsableByteArray buffer)
    throws ParserException {
  try {
    buffer.skipBytes(16); // size(4), width(4), height(4), planes(2), bitcount(2).
    long compression = buffer.readLittleEndianUnsignedInt();
    if (compression == FOURCC_COMPRESSION_DIVX) {
      return new Pair<>(MimeTypes.VIDEO_DIVX, null);
    } else if (compression == FOURCC_COMPRESSION_H263) {
      return new Pair<>(MimeTypes.VIDEO_H263, null);
    } else if (compression == FOURCC_COMPRESSION_VC1) {
      // Search for the initialization data from the end of the BITMAPINFOHEADER. The last 20
      // bytes of which are: sizeImage(4), xPel/m (4), yPel/m (4), clrUsed(4), clrImportant(4).
      int startOffset = buffer.getPosition() + 20;
      byte[] bufferData = buffer.data;
      for (int offset = startOffset; offset < bufferData.length - 4; offset++) {
        if (bufferData[offset] == 0x00
            && bufferData[offset + 1] == 0x00
            && bufferData[offset + 2] == 0x01
            && bufferData[offset + 3] == 0x0F) {
          // We've found the initialization data.
          byte[] initializationData = Arrays.copyOfRange(bufferData, offset, bufferData.length);
          return new Pair<>(MimeTypes.VIDEO_VC1, Collections.singletonList(initializationData));
        }
      }
      throw new ParserException("Failed to find FourCC VC1 initialization data");
    }
  } catch (ArrayIndexOutOfBoundsException e) {
    throw new ParserException("Error parsing FourCC private data");
  }

  Log.w(TAG, "Unknown FourCC. Setting mimeType to " + MimeTypes.VIDEO_UNKNOWN);
  return new Pair<>(MimeTypes.VIDEO_UNKNOWN, null);
}
 
Example #25
Source File: SsManifestParser.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
protected final int parseInt(XmlPullParser parser, String key, int defaultValue)
    throws ParserException {
  String value = parser.getAttributeValue(null, key);
  if (value != null) {
    try {
      return Integer.parseInt(value);
    } catch (NumberFormatException e) {
      throw new ParserException(e);
    }
  } else {
    return defaultValue;
  }
}
 
Example #26
Source File: PlayerEmsgHandler.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private static long getManifestPublishTimeMsInEmsg(EventMessage eventMessage) {
  try {
    return parseXsDateTime(new String(eventMessage.messageData));
  } catch (ParserException ignored) {
    // if we can't parse this event, ignore
    return C.TIME_UNSET;
  }
}
 
Example #27
Source File: LatmReader.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
private int parseAudioSpecificConfig(ParsableBitArray data) throws ParserException {
  int bitsLeft = data.bitsLeft();
  Pair<Integer, Integer> config = CodecSpecificDataUtil.parseAacAudioSpecificConfig(data, true);
  sampleRateHz = config.first;
  channelCount = config.second;
  return bitsLeft - data.bitsLeft();
}
 
Example #28
Source File: WebvttParserUtil.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
/**
 * Reads and validates the first line of a WebVTT file.
 *
 * @param input The input from which the line should be read.
 * @throws ParserException If the line isn't the start of a valid WebVTT file.
 */
public static void validateWebvttHeaderLine(ParsableByteArray input) throws ParserException {
  int startPosition = input.getPosition();
  if (!isWebvttHeaderLine(input)) {
    input.setPosition(startPosition);
    throw new ParserException("Expected WEBVTT. Got " + input.readLine());
  }
}
 
Example #29
Source File: HlsPlaylistParser.java    From MediaSDK with Apache License 2.0 5 votes vote down vote up
@Override
public HlsPlaylist parse(Uri uri, InputStream inputStream) throws IOException {
  BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
  Queue<String> extraLines = new ArrayDeque<>();
  String line;
  try {
    if (!checkPlaylistHeader(reader)) {
      throw new UnrecognizedInputFormatException("Input does not start with the #EXTM3U header.",
          uri);
    }
    while ((line = reader.readLine()) != null) {
      line = line.trim();
      if (line.isEmpty()) {
        // Do nothing.
      } else if (line.startsWith(TAG_STREAM_INF)) {
        extraLines.add(line);
        return parseMasterPlaylist(new LineIterator(extraLines, reader), uri.toString());
      } else if (line.startsWith(TAG_TARGET_DURATION)
          || line.startsWith(TAG_MEDIA_SEQUENCE)
          || line.startsWith(TAG_MEDIA_DURATION)
          || line.startsWith(TAG_KEY)
          || line.startsWith(TAG_BYTERANGE)
          || line.equals(TAG_DISCONTINUITY)
          || line.equals(TAG_DISCONTINUITY_SEQUENCE)
          || line.equals(TAG_ENDLIST)) {
        extraLines.add(line);
        return parseMediaPlaylist(
            masterPlaylist, new LineIterator(extraLines, reader), uri.toString());
      } else {
        extraLines.add(line);
      }
    }
  } finally {
    Util.closeQuietly(reader);
  }
  throw new ParserException("Failed to parse the playlist, could not identify any tags.");
}
 
Example #30
Source File: AtomParsers.java    From TelePlus-Android with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Parses a trak atom (defined in 14496-12).
 *
 * @param trak Atom to decode.
 * @param mvhd Movie header atom, used to get the timescale.
 * @param duration The duration in units of the timescale declared in the mvhd atom, or
 *     {@link C#TIME_UNSET} if the duration should be parsed from the tkhd atom.
 * @param drmInitData {@link DrmInitData} to be included in the format.
 * @param ignoreEditLists Whether to ignore any edit lists in the trak box.
 * @param isQuickTime True for QuickTime media. False otherwise.
 * @return A {@link Track} instance, or {@code null} if the track's type isn't supported.
 */
public static Track parseTrak(Atom.ContainerAtom trak, Atom.LeafAtom mvhd, long duration,
    DrmInitData drmInitData, boolean ignoreEditLists, boolean isQuickTime)
    throws ParserException {
  Atom.ContainerAtom mdia = trak.getContainerAtomOfType(Atom.TYPE_mdia);
  int trackType = parseHdlr(mdia.getLeafAtomOfType(Atom.TYPE_hdlr).data);
  if (trackType == C.TRACK_TYPE_UNKNOWN) {
    return null;
  }

  TkhdData tkhdData = parseTkhd(trak.getLeafAtomOfType(Atom.TYPE_tkhd).data);
  if (duration == C.TIME_UNSET) {
    duration = tkhdData.duration;
  }
  long movieTimescale = parseMvhd(mvhd.data);
  long durationUs;
  if (duration == C.TIME_UNSET) {
    durationUs = C.TIME_UNSET;
  } else {
    durationUs = Util.scaleLargeTimestamp(duration, C.MICROS_PER_SECOND, movieTimescale);
  }
  Atom.ContainerAtom stbl = mdia.getContainerAtomOfType(Atom.TYPE_minf)
      .getContainerAtomOfType(Atom.TYPE_stbl);

  Pair<Long, String> mdhdData = parseMdhd(mdia.getLeafAtomOfType(Atom.TYPE_mdhd).data);
  StsdData stsdData = parseStsd(stbl.getLeafAtomOfType(Atom.TYPE_stsd).data, tkhdData.id,
      tkhdData.rotationDegrees, mdhdData.second, drmInitData, isQuickTime);
  long[] editListDurations = null;
  long[] editListMediaTimes = null;
  if (!ignoreEditLists) {
    Pair<long[], long[]> edtsData = parseEdts(trak.getContainerAtomOfType(Atom.TYPE_edts));
    editListDurations = edtsData.first;
    editListMediaTimes = edtsData.second;
  }
  return stsdData.format == null ? null
      : new Track(tkhdData.id, trackType, mdhdData.first, movieTimescale, durationUs,
          stsdData.format, stsdData.requiredSampleTransformation, stsdData.trackEncryptionBoxes,
          stsdData.nalUnitLengthFieldLength, editListDurations, editListMediaTimes);
}