Java 类com.google.android.exoplayer.util.CodecSpecificDataUtil 实例源码

项目:ExoPlayer-Demo    文件:AudioTagPayloadReader.java   
@Override
protected void parsePayload(ParsableByteArray data, long timeUs) {
  int packetType = data.readUnsignedByte();
  // Parse sequence header just in case it was not done before.
  if (packetType == AAC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) {
    byte[] audioSpecifiConfig = new byte[data.bytesLeft()];
    data.readBytes(audioSpecifiConfig, 0, audioSpecifiConfig.length);
    Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig(
        audioSpecifiConfig);
    MediaFormat mediaFormat = MediaFormat.createAudioFormat(null, MimeTypes.AUDIO_AAC,
        MediaFormat.NO_VALUE, MediaFormat.NO_VALUE, getDurationUs(), audioParams.second,
        audioParams.first, Collections.singletonList(audioSpecifiConfig), null);
    output.format(mediaFormat);
    hasOutputFormat = true;
  } else if (packetType == AAC_PACKET_TYPE_AAC_RAW) {
    // Sample audio AAC frames
    int bytesToWrite = data.bytesLeft();
    output.sampleData(data, bytesToWrite);
    output.sampleMetadata(timeUs, C.SAMPLE_FLAG_SYNC, bytesToWrite, 0, null);
  }
}
项目:miku    文件:AdtsReader.java   
/**
 * Parses the sample header.
 */
private void parseHeader() {
  adtsScratch.setPosition(0);

  if (!hasOutputFormat) {
    int audioObjectType = adtsScratch.readBits(2) + 1;
    int sampleRateIndex = adtsScratch.readBits(4);
    adtsScratch.skipBits(1);
    int channelConfig = adtsScratch.readBits(3);

    byte[] audioSpecificConfig = CodecSpecificDataUtil.buildAacAudioSpecificConfig(
        audioObjectType, sampleRateIndex, channelConfig);
    Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig(
        audioSpecificConfig);

    MediaFormat mediaFormat = MediaFormat.createAudioFormat(MimeTypes.AUDIO_AAC,
        MediaFormat.NO_VALUE, audioParams.second, audioParams.first,
        Collections.singletonList(audioSpecificConfig));
    frameDurationUs = (C.MICROS_PER_SECOND * 1024L) / mediaFormat.sampleRate;
    output.format(mediaFormat);
    hasOutputFormat = true;
  } else {
    adtsScratch.skipBits(10);
  }

  adtsScratch.skipBits(4);
  sampleSize = adtsScratch.readBits(13) - 2 /* the sync word */ - HEADER_SIZE;
  if (hasCrc) {
    sampleSize -= CRC_SIZE;
  }
}
项目:Exoplayer_VLC    文件:AdtsReader.java   
/**
 * Parses the sample header.
 */
private void parseHeader() {
  adtsScratch.setPosition(0);

  if (!hasMediaFormat()) {
    int audioObjectType = adtsScratch.readBits(2) + 1;
    int sampleRateIndex = adtsScratch.readBits(4);
    adtsScratch.skipBits(1);
    int channelConfig = adtsScratch.readBits(3);

    byte[] audioSpecificConfig = CodecSpecificDataUtil.buildAudioSpecificConfig(
        audioObjectType, sampleRateIndex, channelConfig);
    Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAudioSpecificConfig(
        audioSpecificConfig);

    MediaFormat mediaFormat = MediaFormat.createAudioFormat(MimeTypes.AUDIO_AAC,
        MediaFormat.NO_VALUE, audioParams.second, audioParams.first,
        Collections.singletonList(audioSpecificConfig));
    frameDurationUs = (C.MICROS_PER_SECOND * 1024L) / mediaFormat.sampleRate;
    setMediaFormat(mediaFormat);
  } else {
    adtsScratch.skipBits(10);
  }

  adtsScratch.skipBits(4);
  sampleSize = adtsScratch.readBits(13) - 2 /* the sync word */ - HEADER_SIZE;
  if (hasCrc) {
    sampleSize -= CRC_SIZE;
  }
}
项目:Exoplayer_VLC    文件:Mp4Util.java   
/** Constructs and returns a NAL unit with a start code followed by the data in {@code atom}. */
public static byte[] parseChildNalUnit(ParsableByteArray atom) {
  int length = atom.readUnsignedShort();
  int offset = atom.getPosition();
  atom.skip(length);
  return CodecSpecificDataUtil.buildNalUnit(atom.data, offset, length);
}
项目:Exoplayer_VLC    文件:AdtsReader.java   
/**
 * Parses the sample header.
 */
private void parseHeader() {
  adtsScratch.setPosition(0);

  if (!hasMediaFormat()) {
    int audioObjectType = adtsScratch.readBits(2) + 1;
    int sampleRateIndex = adtsScratch.readBits(4);
    adtsScratch.skipBits(1);
    int channelConfig = adtsScratch.readBits(3);

    byte[] audioSpecificConfig = CodecSpecificDataUtil.buildAudioSpecificConfig(
        audioObjectType, sampleRateIndex, channelConfig);
    Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAudioSpecificConfig(
        audioSpecificConfig);

    MediaFormat mediaFormat = MediaFormat.createAudioFormat(MimeTypes.AUDIO_AAC,
        MediaFormat.NO_VALUE, audioParams.second, audioParams.first,
        Collections.singletonList(audioSpecificConfig));
    frameDurationUs = (C.MICROS_PER_SECOND * 1024L) / mediaFormat.sampleRate;
    setMediaFormat(mediaFormat);
  } else {
    adtsScratch.skipBits(10);
  }

  adtsScratch.skipBits(4);
  sampleSize = adtsScratch.readBits(13) - 2 /* the sync word */ - HEADER_SIZE;
  if (hasCrc) {
    sampleSize -= CRC_SIZE;
  }
}
项目:edx-app-android    文件:FragmentedMp4Extractor.java   
private static Pair<MediaFormat, TrackEncryptionBox> parseMp4aFromParent(ParsableByteArray parent,
    int position, int size) {
  parent.setPosition(position + ATOM_HEADER_SIZE);
  // Start of the mp4a atom (defined in 14496-14)
  parent.skip(16);
  int channelCount = parent.readUnsignedShort();
  int sampleSize = parent.readUnsignedShort();
  parent.skip(4);
  int sampleRate = parent.readUnsignedFixedPoint1616();

  byte[] initializationData = null;
  TrackEncryptionBox trackEncryptionBox = null;
  int childPosition = parent.getPosition();
  while (childPosition - position < size) {
    parent.setPosition(childPosition);
    int childStartPosition = parent.getPosition();
    int childAtomSize = parent.readInt();
    int childAtomType = parent.readInt();
    if (childAtomType == Atom.TYPE_esds) {
      initializationData = parseEsdsFromParent(parent, childStartPosition);
      // TODO: Do we really need to do this? See [redacted]
      // Update sampleRate and channelCount from the AudioSpecificConfig initialization data.
      Pair<Integer, Integer> audioSpecificConfig =
          CodecSpecificDataUtil.parseAudioSpecificConfig(initializationData);
      sampleRate = audioSpecificConfig.first;
      channelCount = audioSpecificConfig.second;
    } else if (childAtomType == Atom.TYPE_sinf) {
      trackEncryptionBox = parseSinfFromParent(parent, childStartPosition, childAtomSize);
    }
    childPosition += childAtomSize;
  }

  MediaFormat format = MediaFormat.createAudioFormat("audio/mp4a-latm", sampleSize, channelCount,
      sampleRate, Collections.singletonList(initializationData));
  return Pair.create(format, trackEncryptionBox);
}
项目:ExoPlayer    文件:AdtsReader.java   
/**
 * Parses the sample header.
 */
private void parseHeader() {
  adtsScratch.setPosition(0);

  if (!hasOutputFormat) {
    int audioObjectType = adtsScratch.readBits(2) + 1;
    int sampleRateIndex = adtsScratch.readBits(4);
    adtsScratch.skipBits(1);
    int channelConfig = adtsScratch.readBits(3);

    byte[] audioSpecificConfig = CodecSpecificDataUtil.buildAacAudioSpecificConfig(
        audioObjectType, sampleRateIndex, channelConfig);
    Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig(
        audioSpecificConfig);

    MediaFormat mediaFormat = MediaFormat.createAudioFormat(MimeTypes.AUDIO_AAC,
        MediaFormat.NO_VALUE, audioParams.second, audioParams.first,
        Collections.singletonList(audioSpecificConfig));
    frameDurationUs = (C.MICROS_PER_SECOND * 1024L) / mediaFormat.sampleRate;
    output.format(mediaFormat);
    hasOutputFormat = true;
  } else {
    adtsScratch.skipBits(10);
  }

  adtsScratch.skipBits(4);
  sampleSize = adtsScratch.readBits(13) - 2 /* the sync word */ - HEADER_SIZE;
  if (hasCrc) {
    sampleSize -= CRC_SIZE;
  }
}
项目:miku    文件:AtomParsers.java   
private static void parseAudioSampleEntry(ParsableByteArray parent, int atomType, int position,
    int size, long durationUs, StsdDataHolder out, int entryIndex) {
  parent.setPosition(position + Atom.HEADER_SIZE);
  parent.skipBytes(16);
  int channelCount = parent.readUnsignedShort();
  int sampleSize = parent.readUnsignedShort();
  parent.skipBytes(4);
  int sampleRate = parent.readUnsignedFixedPoint1616();

  // If the atom type determines a MIME type, set it immediately.
  String mimeType = null;
  if (atomType == Atom.TYPE_ac_3) {
    mimeType = MimeTypes.AUDIO_AC3;
  } else if (atomType == Atom.TYPE_ec_3) {
    mimeType = MimeTypes.AUDIO_EC3;
  }

  byte[] initializationData = null;
  int childPosition = parent.getPosition();
  while (childPosition - position < size) {
    parent.setPosition(childPosition);
    int childStartPosition = parent.getPosition();
    int childAtomSize = parent.readInt();
    Assertions.checkArgument(childAtomSize > 0, "childAtomSize should be positive");
    int childAtomType = parent.readInt();
    if (atomType == Atom.TYPE_mp4a || atomType == Atom.TYPE_enca) {
      if (childAtomType == Atom.TYPE_esds) {
        Pair<String, byte[]> mimeTypeAndInitializationData =
            parseEsdsFromParent(parent, childStartPosition);
        mimeType = mimeTypeAndInitializationData.first;
        initializationData = mimeTypeAndInitializationData.second;
        if (MimeTypes.AUDIO_AAC.equals(mimeType)) {
          // TODO: Do we really need to do this? See [Internal: b/10903778]
          // Update sampleRate and channelCount from the AudioSpecificConfig initialization data.
          Pair<Integer, Integer> audioSpecificConfig =
              CodecSpecificDataUtil.parseAacAudioSpecificConfig(initializationData);
          sampleRate = audioSpecificConfig.first;
          channelCount = audioSpecificConfig.second;
        }
      } else if (childAtomType == Atom.TYPE_sinf) {
        out.trackEncryptionBoxes[entryIndex] = parseSinfFromParent(parent, childStartPosition,
            childAtomSize);
      }
    } else if (atomType == Atom.TYPE_ac_3 && childAtomType == Atom.TYPE_dac3) {
      // TODO: Choose the right AC-3 track based on the contents of dac3/dec3.
      // TODO: Add support for encryption (by setting out.trackEncryptionBoxes).
      parent.setPosition(Atom.HEADER_SIZE + childStartPosition);
      out.mediaFormat = Ac3Util.parseAnnexFAc3Format(parent);
      return;
    } else if  (atomType == Atom.TYPE_ec_3 && childAtomType == Atom.TYPE_dec3) {
      parent.setPosition(Atom.HEADER_SIZE + childStartPosition);
      out.mediaFormat = Ac3Util.parseAnnexFEAc3Format(parent);
      return;
    }
    childPosition += childAtomSize;
  }

  // If the media type was not recognized, ignore the track.
  if (mimeType == null) {
    return;
  }

  out.mediaFormat = MediaFormat.createAudioFormat(mimeType, sampleSize, durationUs, channelCount,
      sampleRate,
      initializationData == null ? null : Collections.singletonList(initializationData));
}
项目:miku    文件:SmoothStreamingManifestParser.java   
@Override
public void parseStartTag(XmlPullParser parser) throws ParserException {
  int type = (Integer) getNormalizedAttribute(KEY_TYPE);
  String value;

  index = parseInt(parser, KEY_INDEX, -1);
  bitrate = parseRequiredInt(parser, KEY_BITRATE);

  if (type == StreamElement.TYPE_VIDEO) {
    maxHeight = parseRequiredInt(parser, KEY_MAX_HEIGHT);
    maxWidth = parseRequiredInt(parser, KEY_MAX_WIDTH);
    mimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
  } else {
    maxHeight = -1;
    maxWidth = -1;
    String fourCC = parser.getAttributeValue(null, KEY_FOUR_CC);
    // If fourCC is missing and the stream type is audio, we assume AAC.
    mimeType = fourCC != null ? fourCCToMimeType(fourCC)
        : type == StreamElement.TYPE_AUDIO ? MimeTypes.AUDIO_AAC : null;
  }

  if (type == StreamElement.TYPE_AUDIO) {
    samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
    channels = parseRequiredInt(parser, KEY_CHANNELS);
  } else {
    samplingRate = -1;
    channels = -1;
  }

  value = parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA);
  if (value != null && value.length() > 0) {
    byte[] codecPrivateData = hexStringToByteArray(value);
    byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
    if (split == null) {
      csd.add(codecPrivateData);
    } else {
      for (int i = 0; i < split.length; i++) {
        csd.add(split[i]);
      }
    }
  }
}
项目:ExoPlayer-Demo    文件:AdtsReader.java   
/**
 * Parses the sample header.
 */
private void parseAdtsHeader() {
  adtsScratch.setPosition(0);

  if (!hasOutputFormat) {
    int audioObjectType = adtsScratch.readBits(2) + 1;
    if (audioObjectType != 2) {
      // The stream indicates AAC-Main (1), AAC-SSR (3) or AAC-LTP (4). When the stream indicates
      // AAC-Main it's more likely that the stream contains HE-AAC (5), which cannot be
      // represented correctly in the 2 bit audio_object_type field in the ADTS header. In
      // practice when the stream indicates AAC-SSR or AAC-LTP it more commonly contains AAC-LC or
      // HE-AAC. Since most Android devices don't support AAC-Main, AAC-SSR or AAC-LTP, and since
      // indicating AAC-LC works for HE-AAC streams, we pretend that we're dealing with AAC-LC and
      // hope for the best. In practice this often works.
      // See: https://github.com/google/ExoPlayer/issues/774
      // See: https://github.com/google/ExoPlayer/issues/1383
      Log.w(TAG, "Detected audio object type: " + audioObjectType + ", but assuming AAC LC.");
      audioObjectType = 2;
    }

    int sampleRateIndex = adtsScratch.readBits(4);
    adtsScratch.skipBits(1);
    int channelConfig = adtsScratch.readBits(3);

    byte[] audioSpecificConfig = CodecSpecificDataUtil.buildAacAudioSpecificConfig(
        audioObjectType, sampleRateIndex, channelConfig);
    Pair<Integer, Integer> audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig(
        audioSpecificConfig);

    MediaFormat mediaFormat = MediaFormat.createAudioFormat(null, MimeTypes.AUDIO_AAC,
        MediaFormat.NO_VALUE, MediaFormat.NO_VALUE, C.UNKNOWN_TIME_US, audioParams.second,
        audioParams.first, Collections.singletonList(audioSpecificConfig), null);
    // In this class a sample is an access unit, but the MediaFormat sample rate specifies the
    // number of PCM audio samples per second.
    sampleDurationUs = (C.MICROS_PER_SECOND * 1024) / mediaFormat.sampleRate;
    output.format(mediaFormat);
    hasOutputFormat = true;
  } else {
    adtsScratch.skipBits(10);
  }

  adtsScratch.skipBits(4);
  int sampleSize = adtsScratch.readBits(13) - 2 /* the sync word */ - HEADER_SIZE;
  if (hasCrc) {
    sampleSize -= CRC_SIZE;
  }

  setReadingSampleState(output, sampleDurationUs, 0, sampleSize);
}
项目:ExoPlayer-Demo    文件:SmoothStreamingManifestParser.java   
@Override
public void parseStartTag(XmlPullParser parser) throws ParserException {
  int type = (Integer) getNormalizedAttribute(KEY_TYPE);
  String value;

  index = parseInt(parser, KEY_INDEX, -1);
  bitrate = parseRequiredInt(parser, KEY_BITRATE);
  language = (String) getNormalizedAttribute(KEY_LANGUAGE);

  if (type == StreamElement.TYPE_VIDEO) {
    maxHeight = parseRequiredInt(parser, KEY_MAX_HEIGHT);
    maxWidth = parseRequiredInt(parser, KEY_MAX_WIDTH);
    mimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
  } else {
    maxHeight = -1;
    maxWidth = -1;
    String fourCC = parser.getAttributeValue(null, KEY_FOUR_CC);
    // If fourCC is missing and the stream type is audio, we assume AAC.
    mimeType = fourCC != null ? fourCCToMimeType(fourCC)
        : type == StreamElement.TYPE_AUDIO ? MimeTypes.AUDIO_AAC : null;
  }

  if (type == StreamElement.TYPE_AUDIO) {
    samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
    channels = parseRequiredInt(parser, KEY_CHANNELS);
  } else {
    samplingRate = -1;
    channels = -1;
  }

  value = parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA);
  if (value != null && value.length() > 0) {
    byte[] codecPrivateData = Util.getBytesFromHexString(value);
    byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
    if (split == null) {
      csd.add(codecPrivateData);
    } else {
      for (int i = 0; i < split.length; i++) {
        csd.add(split[i]);
      }
    }
  }
}
项目:android-exoplayer    文件:FragmentedMp4Extractor.java   
private static Pair<MediaFormat, TrackEncryptionBox> parseAudioSampleEntry(
    ParsableByteArray parent, int atomType, int position, int size) {
  parent.setPosition(position + ATOM_HEADER_SIZE);
  parent.skip(16);
  int channelCount = parent.readUnsignedShort();
  int sampleSize = parent.readUnsignedShort();
  parent.skip(4);
  int sampleRate = parent.readUnsignedFixedPoint1616();
  int bitrate = MediaFormat.NO_VALUE;

  byte[] initializationData = null;
  TrackEncryptionBox trackEncryptionBox = null;
  int childPosition = parent.getPosition();
  while (childPosition - position < size) {
    parent.setPosition(childPosition);
    int childStartPosition = parent.getPosition();
    int childAtomSize = parent.readInt();
    int childAtomType = parent.readInt();
    if (atomType == Atom.TYPE_mp4a || atomType == Atom.TYPE_enca) {
      if (childAtomType == Atom.TYPE_esds) {
        initializationData = parseEsdsFromParent(parent, childStartPosition);
        // TODO: Do we really need to do this? See [Internal: b/10903778]
        // Update sampleRate and channelCount from the AudioSpecificConfig initialization data.
        Pair<Integer, Integer> audioSpecificConfig =
            CodecSpecificDataUtil.parseAudioSpecificConfig(initializationData);
        sampleRate = audioSpecificConfig.first;
        channelCount = audioSpecificConfig.second;
      } else if (childAtomType == Atom.TYPE_sinf) {
        trackEncryptionBox = parseSinfFromParent(parent, childStartPosition, childAtomSize);
      }
    } else if (atomType == Atom.TYPE_ac_3 && childAtomType == Atom.TYPE_dac3) {
      // TODO: Choose the right AC-3 track based on the contents of dac3/dec3.
      Ac3Format ac3Format =
          parseAc3SpecificBoxFromParent(parent, childStartPosition);
      if (ac3Format != null) {
        sampleRate = ac3Format.sampleRate;
        channelCount = ac3Format.channelCount;
        bitrate = ac3Format.bitrate;
      }

      // TODO: Add support for encrypted AC-3.
      trackEncryptionBox = null;
    } else if (atomType == Atom.TYPE_ec_3 && childAtomType == Atom.TYPE_dec3) {
      sampleRate = parseEc3SpecificBoxFromParent(parent, childStartPosition);
      trackEncryptionBox = null;
    }
    childPosition += childAtomSize;
  }

  String mimeType;
  if (atomType == Atom.TYPE_ac_3) {
    mimeType = MimeTypes.AUDIO_AC3;
  } else if (atomType == Atom.TYPE_ec_3) {
    mimeType = MimeTypes.AUDIO_EC3;
  } else {
    mimeType = MimeTypes.AUDIO_AAC;
  }

  MediaFormat format = MediaFormat.createAudioFormat(
      mimeType, sampleSize, channelCount, sampleRate, bitrate,
      initializationData == null ? null : Collections.singletonList(initializationData));
  return Pair.create(format, trackEncryptionBox);
}
项目:android-exoplayer    文件:FragmentedMp4Extractor.java   
private static byte[] parseChildNalUnit(ParsableByteArray atom) {
  int length = atom.readUnsignedShort();
  int offset = atom.getPosition();
  atom.skip(length);
  return CodecSpecificDataUtil.buildNalUnit(atom.data, offset, length);
}
项目:android-exoplayer    文件:SmoothStreamingManifestParser.java   
@Override
public void parseStartTag(XmlPullParser parser) throws ParserException {
  int type = (Integer) getNormalizedAttribute(KEY_TYPE);
  content = null;
  String value;

  index = parseInt(parser, KEY_INDEX, -1);
  bitrate = parseRequiredInt(parser, KEY_BITRATE);
  nalUnitLengthField = parseInt(parser, KEY_NAL_UNIT_LENGTH_FIELD, 4);

  if (type == StreamElement.TYPE_VIDEO) {
    maxHeight = parseRequiredInt(parser, KEY_MAX_HEIGHT);
    maxWidth = parseRequiredInt(parser, KEY_MAX_WIDTH);
    mimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
  } else {
    maxHeight = -1;
    maxWidth = -1;
    String fourCC = parser.getAttributeValue(null, KEY_FOUR_CC);
    // If fourCC is missing and the stream type is audio, we assume AAC.
    mimeType = fourCC != null ? fourCCToMimeType(fourCC)
        : type == StreamElement.TYPE_AUDIO ? MimeTypes.AUDIO_AAC : null;
  }

  if (type == StreamElement.TYPE_AUDIO) {
    samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
    channels = parseRequiredInt(parser, KEY_CHANNELS);
    bitPerSample = parseRequiredInt(parser, KEY_BITS_PER_SAMPLE);
    packetSize = parseRequiredInt(parser, KEY_PACKET_SIZE);
    audioTag = parseRequiredInt(parser, KEY_AUDIO_TAG);
  } else {
    samplingRate = -1;
    channels = -1;
    bitPerSample = -1;
    packetSize = -1;
    audioTag = -1;
  }

  value = parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA);
  if (value != null && value.length() > 0) {
    byte[] codecPrivateData = hexStringToByteArray(value);
    byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
    if (split == null) {
      csd.add(codecPrivateData);
    } else {
      for (int i = 0; i < split.length; i++) {
        Pair<Integer, Integer> spsParameters = CodecSpecificDataUtil.parseSpsNalUnit(split[i]);
        if (spsParameters != null) {
          profile = spsParameters.first;
          level = spsParameters.second;
        }
        csd.add(split[i]);
      }
    }
  }
}
项目:Exoplayer_VLC    文件:CommonMp4AtomParsers.java   
private static Pair<MediaFormat, TrackEncryptionBox> parseAudioSampleEntry(
    ParsableByteArray parent, int atomType, int position, int size) {
  parent.setPosition(position + Mp4Util.ATOM_HEADER_SIZE);
  parent.skip(16);
  int channelCount = parent.readUnsignedShort();
  int sampleSize = parent.readUnsignedShort();
  parent.skip(4);
  int sampleRate = parent.readUnsignedFixedPoint1616();
  int bitrate = MediaFormat.NO_VALUE;

  byte[] initializationData = null;
  TrackEncryptionBox trackEncryptionBox = null;
  int childPosition = parent.getPosition();
  while (childPosition - position < size) {
    parent.setPosition(childPosition);
    int childStartPosition = parent.getPosition();
    int childAtomSize = parent.readInt();
    Assertions.checkArgument(childAtomSize > 0, "childAtomSize should be positive");
    int childAtomType = parent.readInt();
    if (atomType == Atom.TYPE_mp4a || atomType == Atom.TYPE_enca) {
      if (childAtomType == Atom.TYPE_esds) {
        initializationData = parseEsdsFromParent(parent, childStartPosition);
        // TODO: Do we really need to do this? See [Internal: b/10903778]
        // Update sampleRate and channelCount from the AudioSpecificConfig initialization data.
        Pair<Integer, Integer> audioSpecificConfig =
            CodecSpecificDataUtil.parseAudioSpecificConfig(initializationData);
        sampleRate = audioSpecificConfig.first;
        channelCount = audioSpecificConfig.second;
      } else if (childAtomType == Atom.TYPE_sinf) {
        trackEncryptionBox = parseSinfFromParent(parent, childStartPosition, childAtomSize);
      }
    } else if (atomType == Atom.TYPE_ac_3 && childAtomType == Atom.TYPE_dac3) {
      // TODO: Choose the right AC-3 track based on the contents of dac3/dec3.
      Ac3Format ac3Format =
          parseAc3SpecificBoxFromParent(parent, childStartPosition);
      if (ac3Format != null) {
        sampleRate = ac3Format.sampleRate;
        channelCount = ac3Format.channelCount;
        bitrate = ac3Format.bitrate;
      }

      // TODO: Add support for encrypted AC-3.
      trackEncryptionBox = null;
    } else if (atomType == Atom.TYPE_ec_3 && childAtomType == Atom.TYPE_dec3) {
      sampleRate = parseEc3SpecificBoxFromParent(parent, childStartPosition);
      trackEncryptionBox = null;
    }
    childPosition += childAtomSize;
  }

  String mimeType;
  if (atomType == Atom.TYPE_ac_3) {
    mimeType = MimeTypes.AUDIO_AC3;
  } else if (atomType == Atom.TYPE_ec_3) {
    mimeType = MimeTypes.AUDIO_EC3;
  } else {
    mimeType = MimeTypes.AUDIO_AAC;
  }

  MediaFormat format = MediaFormat.createAudioFormat(
      mimeType, sampleSize, channelCount, sampleRate, bitrate,
      initializationData == null ? null : Collections.singletonList(initializationData));
  return Pair.create(format, trackEncryptionBox);
}
项目:Exoplayer_VLC    文件:SmoothStreamingManifestParser.java   
@Override
public void parseStartTag(XmlPullParser parser) throws ParserException {
  int type = (Integer) getNormalizedAttribute(KEY_TYPE);
  content = null;
  String value;

  index = parseInt(parser, KEY_INDEX, -1);
  bitrate = parseRequiredInt(parser, KEY_BITRATE);
  nalUnitLengthField = parseInt(parser, KEY_NAL_UNIT_LENGTH_FIELD, 4);

  if (type == StreamElement.TYPE_VIDEO) {
    maxHeight = parseRequiredInt(parser, KEY_MAX_HEIGHT);
    maxWidth = parseRequiredInt(parser, KEY_MAX_WIDTH);
    mimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
  } else {
    maxHeight = -1;
    maxWidth = -1;
    String fourCC = parser.getAttributeValue(null, KEY_FOUR_CC);
    // If fourCC is missing and the stream type is audio, we assume AAC.
    mimeType = fourCC != null ? fourCCToMimeType(fourCC)
        : type == StreamElement.TYPE_AUDIO ? MimeTypes.AUDIO_AAC : null;
  }

  if (type == StreamElement.TYPE_AUDIO) {
    samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
    channels = parseRequiredInt(parser, KEY_CHANNELS);
    bitPerSample = parseRequiredInt(parser, KEY_BITS_PER_SAMPLE);
    packetSize = parseRequiredInt(parser, KEY_PACKET_SIZE);
    audioTag = parseRequiredInt(parser, KEY_AUDIO_TAG);
  } else {
    samplingRate = -1;
    channels = -1;
    bitPerSample = -1;
    packetSize = -1;
    audioTag = -1;
  }

  value = parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA);
  if (value != null && value.length() > 0) {
    byte[] codecPrivateData = hexStringToByteArray(value);
    byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
    if (split == null) {
      csd.add(codecPrivateData);
    } else {
      for (int i = 0; i < split.length; i++) {
        Pair<Integer, Integer> spsParameters = CodecSpecificDataUtil.parseSpsNalUnit(split[i]);
        if (spsParameters != null) {
          profile = spsParameters.first;
          level = spsParameters.second;
        }
        csd.add(split[i]);
      }
    }
  }
}
项目:edx-app-android    文件:FragmentedMp4Extractor.java   
private static byte[] parseChildNalUnit(ParsableByteArray atom) {
  int length = atom.readUnsignedShort();
  int offset = atom.getPosition();
  atom.skip(length);
  return CodecSpecificDataUtil.buildNalUnit(atom.data, offset, length);
}
项目:edx-app-android    文件:SmoothStreamingManifestParser.java   
@Override
public void parseStartTag(XmlPullParser parser) throws ParserException {
  int type = (Integer) getNormalizedAttribute(KEY_TYPE);
  content = null;
  String value;

  index = parseInt(parser, KEY_INDEX, -1);
  bitrate = parseRequiredInt(parser, KEY_BITRATE);
  nalUnitLengthField = parseInt(parser, KEY_NAL_UNIT_LENGTH_FIELD, 4);

  if (type == StreamElement.TYPE_VIDEO) {
    maxHeight = parseRequiredInt(parser, KEY_MAX_HEIGHT);
    maxWidth = parseRequiredInt(parser, KEY_MAX_WIDTH);
    fourCC = parseRequiredString(parser, KEY_FOUR_CC);
  } else {
    maxHeight = -1;
    maxWidth = -1;
    fourCC = parser.getAttributeValue(null, KEY_FOUR_CC);
  }

  if (type == StreamElement.TYPE_AUDIO) {
    samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
    channels = parseRequiredInt(parser, KEY_CHANNELS);
    bitPerSample = parseRequiredInt(parser, KEY_BITS_PER_SAMPLE);
    packetSize = parseRequiredInt(parser, KEY_PACKET_SIZE);
    audioTag = parseRequiredInt(parser, KEY_AUDIO_TAG);
  } else {
    samplingRate = -1;
    channels = -1;
    bitPerSample = -1;
    packetSize = -1;
    audioTag = -1;
  }

  value = parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA);
  if (value != null && value.length() > 0) {
    byte[] codecPrivateData = hexStringToByteArray(value);
    byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
    if (split == null) {
      csd.add(codecPrivateData);
    } else {
      for (int i = 0; i < split.length; i++) {
        Pair<Integer, Integer> spsParameters = CodecSpecificDataUtil.parseSpsNalUnit(split[i]);
        if (spsParameters != null) {
          profile = spsParameters.first;
          level = spsParameters.second;
        }
        csd.add(split[i]);
      }
    }
  }
}
项目:ExoPlayer    文件:AtomParsers.java   
private static void parseAudioSampleEntry(ParsableByteArray parent, int atomType, int position,
    int size, long durationUs, StsdDataHolder out, int entryIndex) {
  parent.setPosition(position + Atom.HEADER_SIZE);
  parent.skipBytes(16);
  int channelCount = parent.readUnsignedShort();
  int sampleSize = parent.readUnsignedShort();
  parent.skipBytes(4);
  int sampleRate = parent.readUnsignedFixedPoint1616();

  // If the atom type determines a MIME type, set it immediately.
  String mimeType = null;
  if (atomType == Atom.TYPE_ac_3) {
    mimeType = MimeTypes.AUDIO_AC3;
  } else if (atomType == Atom.TYPE_ec_3) {
    mimeType = MimeTypes.AUDIO_EC3;
  }

  byte[] initializationData = null;
  int childPosition = parent.getPosition();
  while (childPosition - position < size) {
    parent.setPosition(childPosition);
    int childStartPosition = parent.getPosition();
    int childAtomSize = parent.readInt();
    Assertions.checkArgument(childAtomSize > 0, "childAtomSize should be positive");
    int childAtomType = parent.readInt();
    if (atomType == Atom.TYPE_mp4a || atomType == Atom.TYPE_enca) {
      if (childAtomType == Atom.TYPE_esds) {
        Pair<String, byte[]> mimeTypeAndInitializationData =
            parseEsdsFromParent(parent, childStartPosition);
        mimeType = mimeTypeAndInitializationData.first;
        initializationData = mimeTypeAndInitializationData.second;
        if (MimeTypes.AUDIO_AAC.equals(mimeType)) {
          // TODO: Do we really need to do this? See [Internal: b/10903778]
          // Update sampleRate and channelCount from the AudioSpecificConfig initialization data.
          Pair<Integer, Integer> audioSpecificConfig =
              CodecSpecificDataUtil.parseAacAudioSpecificConfig(initializationData);
          sampleRate = audioSpecificConfig.first;
          channelCount = audioSpecificConfig.second;
        }
      } else if (childAtomType == Atom.TYPE_sinf) {
        out.trackEncryptionBoxes[entryIndex] = parseSinfFromParent(parent, childStartPosition,
            childAtomSize);
      }
    } else if (atomType == Atom.TYPE_ac_3 && childAtomType == Atom.TYPE_dac3) {
      // TODO: Choose the right AC-3 track based on the contents of dac3/dec3.
      // TODO: Add support for encryption (by setting out.trackEncryptionBoxes).
      parent.setPosition(Atom.HEADER_SIZE + childStartPosition);
      out.mediaFormat = Ac3Util.parseAnnexFAc3Format(parent);
      return;
    } else if  (atomType == Atom.TYPE_ec_3 && childAtomType == Atom.TYPE_dec3) {
      parent.setPosition(Atom.HEADER_SIZE + childStartPosition);
      out.mediaFormat = Ac3Util.parseAnnexFEAc3Format(parent);
      return;
    }
    childPosition += childAtomSize;
  }

  // If the media type was not recognized, ignore the track.
  if (mimeType == null) {
    return;
  }

  out.mediaFormat = MediaFormat.createAudioFormat(mimeType, sampleSize, durationUs, channelCount,
      sampleRate,
      initializationData == null ? null : Collections.singletonList(initializationData));
}
项目:ExoPlayer    文件:SmoothStreamingManifestParser.java   
@Override
public void parseStartTag(XmlPullParser parser) throws ParserException {
  int type = (Integer) getNormalizedAttribute(KEY_TYPE);
  String value;

  index = parseInt(parser, KEY_INDEX, -1);
  bitrate = parseRequiredInt(parser, KEY_BITRATE);

  if (type == StreamElement.TYPE_VIDEO) {
    maxHeight = parseRequiredInt(parser, KEY_MAX_HEIGHT);
    maxWidth = parseRequiredInt(parser, KEY_MAX_WIDTH);
    mimeType = fourCCToMimeType(parseRequiredString(parser, KEY_FOUR_CC));
  } else {
    maxHeight = -1;
    maxWidth = -1;
    String fourCC = parser.getAttributeValue(null, KEY_FOUR_CC);
    // If fourCC is missing and the stream type is audio, we assume AAC.
    mimeType = fourCC != null ? fourCCToMimeType(fourCC)
        : type == StreamElement.TYPE_AUDIO ? MimeTypes.AUDIO_AAC : null;
  }

  if (type == StreamElement.TYPE_AUDIO) {
    samplingRate = parseRequiredInt(parser, KEY_SAMPLING_RATE);
    channels = parseRequiredInt(parser, KEY_CHANNELS);
  } else {
    samplingRate = -1;
    channels = -1;
  }

  value = parser.getAttributeValue(null, KEY_CODEC_PRIVATE_DATA);
  if (value != null && value.length() > 0) {
    byte[] codecPrivateData = hexStringToByteArray(value);
    byte[][] split = CodecSpecificDataUtil.splitNalUnits(codecPrivateData);
    if (split == null) {
      csd.add(codecPrivateData);
    } else {
      for (int i = 0; i < split.length; i++) {
        csd.add(split[i]);
      }
    }
  }
}