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

项目:miku    文件:AtomParsers.java   
private static Pair<List<byte[]>, Integer> parseAvcCFromParent(ParsableByteArray parent,
    int position) {
  parent.setPosition(position + Atom.HEADER_SIZE + 4);
  // Start of the AVCDecoderConfigurationRecord (defined in 14496-15)
  int nalUnitLengthFieldLength = (parent.readUnsignedByte() & 0x3) + 1;
  if (nalUnitLengthFieldLength == 3) {
    throw new IllegalStateException();
  }
  List<byte[]> initializationData = new ArrayList<>();
  // TODO: We should try and parse these using CodecSpecificDataUtil.parseSpsNalUnit, and
  // expose the AVC profile and level somewhere useful; Most likely in MediaFormat.
  int numSequenceParameterSets = parent.readUnsignedByte() & 0x1F;
  for (int j = 0; j < numSequenceParameterSets; j++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(parent));
  }
  int numPictureParameterSets = parent.readUnsignedByte();
  for (int j = 0; j < numPictureParameterSets; j++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(parent));
  }
  return Pair.create(initializationData, nalUnitLengthFieldLength);
}
项目:miku    文件:WebmExtractor.java   
/**
 * Builds initialization data for a {@link MediaFormat} from H.264 (AVC) codec private data.
 *
 * @return The initialization data for the {@link MediaFormat}.
 * @throws ParserException If the initialization data could not be built.
 */
private static Pair<List<byte[]>, Integer> parseAvcCodecPrivate(ParsableByteArray buffer)
    throws ParserException {
  try {
    // TODO: Deduplicate with AtomParsers.parseAvcCFromParent.
    buffer.setPosition(4);
    int nalUnitLengthFieldLength = (buffer.readUnsignedByte() & 0x03) + 1;
    Assertions.checkState(nalUnitLengthFieldLength != 3);
    List<byte[]> initializationData = new ArrayList<>();
    int numSequenceParameterSets = buffer.readUnsignedByte() & 0x1F;
    for (int i = 0; i < numSequenceParameterSets; i++) {
      initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
    }
    int numPictureParameterSets = buffer.readUnsignedByte();
    for (int j = 0; j < numPictureParameterSets; j++) {
      initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
    }
    return Pair.create(initializationData, nalUnitLengthFieldLength);
  } catch (ArrayIndexOutOfBoundsException e) {
    throw new ParserException("Error parsing AVC codec private");
  }
}
项目:ExoPlayer-Demo    文件:WebmExtractor.java   
/**
 * Builds initialization data for a {@link MediaFormat} from H.264 (AVC) codec private data.
 *
 * @return The initialization data for the {@link MediaFormat}.
 * @throws ParserException If the initialization data could not be built.
 */
private static Pair<List<byte[]>, Integer> parseAvcCodecPrivate(ParsableByteArray buffer)
    throws ParserException {
  try {
    // TODO: Deduplicate with AtomParsers.parseAvcCFromParent.
    buffer.setPosition(4);
    int nalUnitLengthFieldLength = (buffer.readUnsignedByte() & 0x03) + 1;
    if (nalUnitLengthFieldLength == 3) {
      throw new ParserException();
    }
    List<byte[]> initializationData = new ArrayList<>();
    int numSequenceParameterSets = buffer.readUnsignedByte() & 0x1F;
    for (int i = 0; i < numSequenceParameterSets; i++) {
      initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
    }
    int numPictureParameterSets = buffer.readUnsignedByte();
    for (int j = 0; j < numPictureParameterSets; j++) {
      initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
    }
    return Pair.create(initializationData, nalUnitLengthFieldLength);
  } catch (ArrayIndexOutOfBoundsException e) {
    throw new ParserException("Error parsing AVC codec private");
  }
}
项目:ExoPlayer    文件:AtomParsers.java   
private static Pair<List<byte[]>, Integer> parseAvcCFromParent(ParsableByteArray parent,
    int position) {
  parent.setPosition(position + Atom.HEADER_SIZE + 4);
  // Start of the AVCDecoderConfigurationRecord (defined in 14496-15)
  int nalUnitLengthFieldLength = (parent.readUnsignedByte() & 0x3) + 1;
  if (nalUnitLengthFieldLength == 3) {
    throw new IllegalStateException();
  }
  List<byte[]> initializationData = new ArrayList<>();
  // TODO: We should try and parse these using CodecSpecificDataUtil.parseSpsNalUnit, and
  // expose the AVC profile and level somewhere useful; Most likely in MediaFormat.
  int numSequenceParameterSets = parent.readUnsignedByte() & 0x1F;
  for (int j = 0; j < numSequenceParameterSets; j++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(parent));
  }
  int numPictureParameterSets = parent.readUnsignedByte();
  for (int j = 0; j < numPictureParameterSets; j++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(parent));
  }
  return Pair.create(initializationData, nalUnitLengthFieldLength);
}
项目:ExoPlayer    文件:WebmExtractor.java   
/**
 * Builds initialization data for a {@link MediaFormat} from H.264 (AVC) codec private data.
 *
 * @return The initialization data for the {@link MediaFormat}.
 * @throws ParserException If the initialization data could not be built.
 */
private static Pair<List<byte[]>, Integer> parseAvcCodecPrivate(ParsableByteArray buffer)
    throws ParserException {
  try {
    // TODO: Deduplicate with AtomParsers.parseAvcCFromParent.
    buffer.setPosition(4);
    int nalUnitLengthFieldLength = (buffer.readUnsignedByte() & 0x03) + 1;
    Assertions.checkState(nalUnitLengthFieldLength != 3);
    List<byte[]> initializationData = new ArrayList<>();
    int numSequenceParameterSets = buffer.readUnsignedByte() & 0x1F;
    for (int i = 0; i < numSequenceParameterSets; i++) {
      initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
    }
    int numPictureParameterSets = buffer.readUnsignedByte();
    for (int j = 0; j < numPictureParameterSets; j++) {
      initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
    }
    return Pair.create(initializationData, nalUnitLengthFieldLength);
  } catch (ArrayIndexOutOfBoundsException e) {
    throw new ParserException("Error parsing AVC codec private");
  }
}
项目:miku    文件:H264Reader.java   
@Override
public void seek() {
  seiReader.seek();
  NalUnitUtil.clearPrefixFlags(prefixFlags);
  sps.reset();
  pps.reset();
  sei.reset();
  if (ifrParserBuffer != null) {
    ifrParserBuffer.reset();
  }
  foundFirstSample = false;
  totalBytesWritten = 0;
}
项目:miku    文件:H264Reader.java   
private void feedNalUnitTargetEnd(long pesTimeUs, int discardPadding) {
  sps.endNalUnit(discardPadding);
  pps.endNalUnit(discardPadding);
  if (sei.endNalUnit(discardPadding)) {
    int unescapedLength = NalUnitUtil.unescapeStream(sei.nalData, sei.nalLength);
    seiWrapper.reset(sei.nalData, unescapedLength);
    seiWrapper.setPosition(4); // NAL prefix and nal_unit() header.
    seiReader.consume(seiWrapper, pesTimeUs, true);
  }
}
项目:miku    文件:H265Reader.java   
@Override
public void seek() {
  seiReader.seek();
  NalUnitUtil.clearPrefixFlags(prefixFlags);
  vps.reset();
  sps.reset();
  pps.reset();
  prefixSei.reset();
  suffixSei.reset();
  foundFirstSample = false;
  totalBytesWritten = 0;
}
项目:miku    文件:Mp4Extractor.java   
public Mp4Extractor() {
  atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE);
  containerAtoms = new Stack<>();
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  enterReadingAtomHeaderState();
}
项目:miku    文件:FragmentedMp4Extractor.java   
/**
 * @param workaroundFlags Flags to allow parsing of faulty streams.
 *     {@link #WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME} is currently the only flag defined.
 */
public FragmentedMp4Extractor(int workaroundFlags) {
  this.workaroundFlags = workaroundFlags;
  atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE);
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  encryptionSignalByte = new ParsableByteArray(1);
  extendedTypeScratch = new byte[16];
  containerAtoms = new Stack<>();
  fragmentRun = new TrackFragment();
  enterReadingAtomHeaderState();
}
项目:miku    文件:WebmExtractor.java   
WebmExtractor(EbmlReader reader) {
  this.reader = reader;
  this.reader.init(new InnerEbmlReaderOutput());
  varintReader = new VarintReader();
  scratch = new ParsableByteArray(4);
  vorbisNumPageSamples = new ParsableByteArray(ByteBuffer.allocate(4).putInt(-1).array());
  seekEntryIdBytes = new ParsableByteArray(4);
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  sampleStrippedBytes = new ParsableByteArray();
}
项目:ExoPlayer-Demo    文件:H262Reader.java   
@Override
public void seek() {
  NalUnitUtil.clearPrefixFlags(prefixFlags);
  csdBuffer.reset();
  pesPtsUsAvailable = false;
  foundFirstFrameInGroup = false;
  totalBytesWritten = 0;
}
项目:ExoPlayer-Demo    文件:H264Reader.java   
@Override
public void seek() {
  NalUnitUtil.clearPrefixFlags(prefixFlags);
  sps.reset();
  pps.reset();
  sei.reset();
  sampleReader.reset();
  totalBytesWritten = 0;
}
项目:ExoPlayer-Demo    文件:H265Reader.java   
@Override
public void seek() {
  NalUnitUtil.clearPrefixFlags(prefixFlags);
  vps.reset();
  sps.reset();
  pps.reset();
  prefixSei.reset();
  suffixSei.reset();
  sampleReader.reset();
  totalBytesWritten = 0;
}
项目:ExoPlayer-Demo    文件:AtomParsers.java   
private static AvcCData parseAvcCFromParent(ParsableByteArray parent, int position) {
  parent.setPosition(position + Atom.HEADER_SIZE + 4);
  // Start of the AVCDecoderConfigurationRecord (defined in 14496-15)
  int nalUnitLengthFieldLength = (parent.readUnsignedByte() & 0x3) + 1;
  if (nalUnitLengthFieldLength == 3) {
    throw new IllegalStateException();
  }
  List<byte[]> initializationData = new ArrayList<>();
  float pixelWidthAspectRatio = 1;
  int numSequenceParameterSets = parent.readUnsignedByte() & 0x1F;
  for (int j = 0; j < numSequenceParameterSets; j++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(parent));
  }
  int numPictureParameterSets = parent.readUnsignedByte();
  for (int j = 0; j < numPictureParameterSets; j++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(parent));
  }

  if (numSequenceParameterSets > 0) {
    // Parse the first sequence parameter set to obtain pixelWidthAspectRatio.
    ParsableBitArray spsDataBitArray = new ParsableBitArray(initializationData.get(0));
    // Skip the NAL header consisting of the nalUnitLengthField and the type (1 byte).
    spsDataBitArray.setPosition(8 * (nalUnitLengthFieldLength + 1));
    pixelWidthAspectRatio = NalUnitUtil.parseSpsNalUnit(spsDataBitArray).pixelWidthAspectRatio;
  }

  return new AvcCData(initializationData, nalUnitLengthFieldLength, pixelWidthAspectRatio);
}
项目:ExoPlayer-Demo    文件:Mp4Extractor.java   
public Mp4Extractor() {
  atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE);
  containerAtoms = new Stack<>();
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  enterReadingAtomHeaderState();
}
项目:ExoPlayer-Demo    文件:FragmentedMp4Extractor.java   
/**
 * @param flags Flags to allow parsing of faulty streams.
 * @param sideloadedTrack Sideloaded track information, in the case that the extractor
 *     will not receive a moov box in the input data.
 */
public FragmentedMp4Extractor(int flags, Track sideloadedTrack) {
  this.sideloadedTrack = sideloadedTrack;
  this.flags = flags | (sideloadedTrack != null ? FLAG_SIDELOADED : 0);
  atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE);
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  encryptionSignalByte = new ParsableByteArray(1);
  extendedTypeScratch = new byte[16];
  containerAtoms = new Stack<>();
  trackBundles = new SparseArray<>();
  enterReadingAtomHeaderState();
}
项目:ExoPlayer-Demo    文件:VideoTagPayloadReader.java   
/**
 * Builds initialization data for a {@link MediaFormat} from H.264 (AVC) codec private data.
 *
 * @return The AvcSequenceHeader data needed to initialize the video codec.
 * @throws ParserException If the initialization data could not be built.
 */
private AvcSequenceHeaderData parseAvcCodecPrivate(ParsableByteArray buffer)
    throws ParserException {
  // TODO: Deduplicate with AtomParsers.parseAvcCFromParent.
  buffer.setPosition(4);
  int nalUnitLengthFieldLength = (buffer.readUnsignedByte() & 0x03) + 1;
  Assertions.checkState(nalUnitLengthFieldLength != 3);
  List<byte[]> initializationData = new ArrayList<>();
  int numSequenceParameterSets = buffer.readUnsignedByte() & 0x1F;
  for (int i = 0; i < numSequenceParameterSets; i++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
  }
  int numPictureParameterSets = buffer.readUnsignedByte();
  for (int j = 0; j < numPictureParameterSets; j++) {
    initializationData.add(NalUnitUtil.parseChildNalUnit(buffer));
  }

  float pixelWidthAspectRatio = 1;
  int width = MediaFormat.NO_VALUE;
  int height = MediaFormat.NO_VALUE;
  if (numSequenceParameterSets > 0) {
    // Parse the first sequence parameter set to obtain pixelWidthAspectRatio.
    ParsableBitArray spsDataBitArray = new ParsableBitArray(initializationData.get(0));
    // Skip the NAL header consisting of the nalUnitLengthField and the type (1 byte).
    spsDataBitArray.setPosition(8 * (nalUnitLengthFieldLength + 1));
    NalUnitUtil.SpsData sps = NalUnitUtil.parseSpsNalUnit(spsDataBitArray);
    width = sps.width;
    height = sps.height;
    pixelWidthAspectRatio = sps.pixelWidthAspectRatio;
  }

  return new AvcSequenceHeaderData(initializationData, nalUnitLengthFieldLength,
      width, height, pixelWidthAspectRatio);
}
项目:ExoPlayer-Demo    文件:WebmExtractor.java   
WebmExtractor(EbmlReader reader) {
  this.reader = reader;
  this.reader.init(new InnerEbmlReaderOutput());
  varintReader = new VarintReader();
  tracks = new SparseArray<>();
  scratch = new ParsableByteArray(4);
  vorbisNumPageSamples = new ParsableByteArray(ByteBuffer.allocate(4).putInt(-1).array());
  seekEntryIdBytes = new ParsableByteArray(4);
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  sampleStrippedBytes = new ParsableByteArray();
  subripSample = new ParsableByteArray();
}
项目:ExoPlayer    文件:H264Reader.java   
@Override
public void seek() {
  seiReader.seek();
  NalUnitUtil.clearPrefixFlags(prefixFlags);
  sps.reset();
  pps.reset();
  sei.reset();
  if (ifrParserBuffer != null) {
    ifrParserBuffer.reset();
  }
  foundFirstSample = false;
  totalBytesWritten = 0;
}
项目:ExoPlayer    文件:H264Reader.java   
private void feedNalUnitTargetEnd(long pesTimeUs, int discardPadding) {
  sps.endNalUnit(discardPadding);
  pps.endNalUnit(discardPadding);
  if (sei.endNalUnit(discardPadding)) {
    int unescapedLength = NalUnitUtil.unescapeStream(sei.nalData, sei.nalLength);
    seiWrapper.reset(sei.nalData, unescapedLength);
    seiWrapper.setPosition(4); // NAL prefix and nal_unit() header.
    seiReader.consume(seiWrapper, pesTimeUs, true);
  }
}
项目:ExoPlayer    文件:H265Reader.java   
@Override
public void seek() {
  seiReader.seek();
  NalUnitUtil.clearPrefixFlags(prefixFlags);
  vps.reset();
  sps.reset();
  pps.reset();
  prefixSei.reset();
  suffixSei.reset();
  foundFirstSample = false;
  totalBytesWritten = 0;
}
项目:ExoPlayer    文件:Mp4Extractor.java   
public Mp4Extractor() {
  atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE);
  containerAtoms = new Stack<>();
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  enterReadingAtomHeaderState();
}
项目:ExoPlayer    文件:FragmentedMp4Extractor.java   
/**
 * @param workaroundFlags Flags to allow parsing of faulty streams.
 *     {@link #WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME} is currently the only flag defined.
 */
public FragmentedMp4Extractor(int workaroundFlags) {
  this.workaroundFlags = workaroundFlags;
  atomHeader = new ParsableByteArray(Atom.LONG_HEADER_SIZE);
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  encryptionSignalByte = new ParsableByteArray(1);
  extendedTypeScratch = new byte[16];
  containerAtoms = new Stack<>();
  fragmentRun = new TrackFragment();
  enterReadingAtomHeaderState();
}
项目:ExoPlayer    文件:WebmExtractor.java   
WebmExtractor(EbmlReader reader) {
  this.reader = reader;
  this.reader.init(new InnerEbmlReaderOutput());
  varintReader = new VarintReader();
  scratch = new ParsableByteArray(4);
  vorbisNumPageSamples = new ParsableByteArray(ByteBuffer.allocate(4).putInt(-1).array());
  seekEntryIdBytes = new ParsableByteArray(4);
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
  sampleStrippedBytes = new ParsableByteArray();
}
项目:miku    文件:H264Reader.java   
@Override
public void consume(ParsableByteArray data, long pesTimeUs, boolean startOfPacket) {
  while (data.bytesLeft() > 0) {
    int offset = data.getPosition();
    int limit = data.limit();
    byte[] dataArray = data.data;

    // Append the data to the buffer.
    totalBytesWritten += data.bytesLeft();
    output.sampleData(data, data.bytesLeft());

    // Scan the appended data, processing NAL units as they are encountered
    while (offset < limit) {
      int nextNalUnitOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);
      if (nextNalUnitOffset < limit) {
        // We've seen the start of a NAL unit.

        // This is the length to the start of the unit. It may be negative if the NAL unit
        // actually started in previously consumed data.
        int lengthToNalUnit = nextNalUnitOffset - offset;
        if (lengthToNalUnit > 0) {
          feedNalUnitTargetBuffersData(dataArray, offset, nextNalUnitOffset);
        }

        int nalUnitType = NalUnitUtil.getNalUnitType(dataArray, nextNalUnitOffset);
        int bytesWrittenPastNalUnit = limit - nextNalUnitOffset;
        switch (nalUnitType) {
          case NAL_UNIT_TYPE_IDR:
            isKeyframe = true;
            break;
          case NAL_UNIT_TYPE_AUD:
            if (foundFirstSample) {
              if (ifrParserBuffer != null && ifrParserBuffer.isCompleted()) {
                int sliceType = ifrParserBuffer.getSliceType();
                isKeyframe |= (sliceType == FRAME_TYPE_I || sliceType == FRAME_TYPE_ALL_I);
                ifrParserBuffer.reset();
              }
              if (isKeyframe && !hasOutputFormat && sps.isCompleted() && pps.isCompleted()) {
                parseMediaFormat(sps, pps);
              }
              int flags = isKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
              int size = (int) (totalBytesWritten - samplePosition) - bytesWrittenPastNalUnit;
              output.sampleMetadata(sampleTimeUs, flags, size, bytesWrittenPastNalUnit, null);
            }
            foundFirstSample = true;
            samplePosition = totalBytesWritten - bytesWrittenPastNalUnit;
            sampleTimeUs = pesTimeUs;
            isKeyframe = false;
            break;
        }

        // If the length to the start of the unit is negative then we wrote too many bytes to the
        // NAL buffers. Discard the excess bytes when notifying that the unit has ended.
        feedNalUnitTargetEnd(pesTimeUs, lengthToNalUnit < 0 ? -lengthToNalUnit : 0);
        // Notify the start of the next NAL unit.
        feedNalUnitTargetBuffersStart(nalUnitType);
        // Continue scanning the data.
        offset = nextNalUnitOffset + 3;
      } else {
        feedNalUnitTargetBuffersData(dataArray, offset, limit);
        offset = limit;
      }
    }
  }
}
项目:miku    文件:H265Reader.java   
@Override
public void consume(ParsableByteArray data, long pesTimeUs, boolean startOfPacket) {
  while (data.bytesLeft() > 0) {
    int offset = data.getPosition();
    int limit = data.limit();
    byte[] dataArray = data.data;

    // Append the data to the buffer.
    totalBytesWritten += data.bytesLeft();
    output.sampleData(data, data.bytesLeft());

    // Scan the appended data, processing NAL units as they are encountered
    while (offset < limit) {
      int nextNalUnitOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);
      if (nextNalUnitOffset < limit) {
        // We've seen the start of a NAL unit.

        // This is the length to the start of the unit. It may be negative if the NAL unit
        // actually started in previously consumed data.
        int lengthToNalUnit = nextNalUnitOffset - offset;
        if (lengthToNalUnit > 0) {
          feedNalUnitTargetBuffersData(dataArray, offset, nextNalUnitOffset);
        }

        int nalUnitType = NalUnitUtil.getH265NalUnitType(dataArray, nextNalUnitOffset);
        int bytesWrittenPastNalUnit = limit - nextNalUnitOffset;
        if (isFirstSliceSegmentInPic(dataArray, nextNalUnitOffset)) {
          if (foundFirstSample) {
            if (isKeyframe && !hasOutputFormat && vps.isCompleted() && sps.isCompleted()
                && pps.isCompleted()) {
              parseMediaFormat(vps, sps, pps);
            }
            int flags = isKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
            int size = (int) (totalBytesWritten - samplePosition) - bytesWrittenPastNalUnit;
            output.sampleMetadata(sampleTimeUs, flags, size, bytesWrittenPastNalUnit, null);
          }
          foundFirstSample = true;
          samplePosition = totalBytesWritten - bytesWrittenPastNalUnit;
          sampleTimeUs = pesTimeUs;
          isKeyframe = isRandomAccessPoint(nalUnitType);
        }

        // If the length to the start of the unit is negative then we wrote too many bytes to the
        // NAL buffers. Discard the excess bytes when notifying that the unit has ended.
        feedNalUnitTargetEnd(pesTimeUs, lengthToNalUnit < 0 ? -lengthToNalUnit : 0);
        // Notify the start of the next NAL unit.
        feedNalUnitTargetBuffersStart(nalUnitType);
        // Continue scanning the data.
        offset = nextNalUnitOffset + 3;
      } else {
        feedNalUnitTargetBuffersData(dataArray, offset, limit);
        offset = limit;
      }
    }
  }
}
项目:ExoPlayer-Demo    文件:H262Reader.java   
@Override
public void consume(ParsableByteArray data) {
  while (data.bytesLeft() > 0) {
    int offset = data.getPosition();
    int limit = data.limit();
    byte[] dataArray = data.data;

    // Append the data to the buffer.
    totalBytesWritten += data.bytesLeft();
    output.sampleData(data, data.bytesLeft());

    int searchOffset = offset;
    while (true) {
      int startCodeOffset = NalUnitUtil.findNalUnit(dataArray, searchOffset, limit, prefixFlags);

      if (startCodeOffset == limit) {
        // We've scanned to the end of the data without finding another start code.
        if (!hasOutputFormat) {
          csdBuffer.onData(dataArray, offset, limit);
        }
        return;
      }

      // We've found a start code with the following value.
      int startCodeValue = data.data[startCodeOffset + 3] & 0xFF;

      if (!hasOutputFormat) {
        // This is the number of bytes from the current offset to the start of the next start
        // code. It may be negative if the start code started in the previously consumed data.
        int lengthToStartCode = startCodeOffset - offset;
        if (lengthToStartCode > 0) {
          csdBuffer.onData(dataArray, offset, startCodeOffset);
        }
        // This is the number of bytes belonging to the next start code that have already been
        // passed to csdDataTargetBuffer.
        int bytesAlreadyPassed = lengthToStartCode < 0 ? -lengthToStartCode : 0;
        if (csdBuffer.onStartCode(startCodeValue, bytesAlreadyPassed)) {
          // The csd data is complete, so we can parse and output the media format.
          Pair<MediaFormat, Long> result = parseCsdBuffer(csdBuffer);
          output.format(result.first);
          frameDurationUs = result.second;
          hasOutputFormat = true;
        }
      }

      if (hasOutputFormat && (startCodeValue == START_GROUP || startCodeValue == START_PICTURE)) {
        int bytesWrittenPastStartCode = limit - startCodeOffset;
        if (foundFirstFrameInGroup) {
          int flags = isKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
          int size = (int) (totalBytesWritten - framePosition) - bytesWrittenPastStartCode;
          output.sampleMetadata(frameTimeUs, flags, size, bytesWrittenPastStartCode, null);
          isKeyframe = false;
        }
        if (startCodeValue == START_GROUP) {
          foundFirstFrameInGroup = false;
          isKeyframe = true;
        } else /* startCode == START_PICTURE */ {
          frameTimeUs = pesPtsUsAvailable ? pesTimeUs : (frameTimeUs + frameDurationUs);
          framePosition = totalBytesWritten - bytesWrittenPastStartCode;
          pesPtsUsAvailable = false;
          foundFirstFrameInGroup = true;
        }
      }

      offset = startCodeOffset;
      searchOffset = offset + 3;
    }
  }
}
项目:ExoPlayer-Demo    文件:H264Reader.java   
@Override
public void consume(ParsableByteArray data) {
  while (data.bytesLeft() > 0) {
    int offset = data.getPosition();
    int limit = data.limit();
    byte[] dataArray = data.data;

    // Append the data to the buffer.
    totalBytesWritten += data.bytesLeft();
    output.sampleData(data, data.bytesLeft());

    // Scan the appended data, processing NAL units as they are encountered
    while (true) {
      int nalUnitOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);

      if (nalUnitOffset == limit) {
        // We've scanned to the end of the data without finding the start of another NAL unit.
        nalUnitData(dataArray, offset, limit);
        return;
      }

      // We've seen the start of a NAL unit of the following type.
      int nalUnitType = NalUnitUtil.getNalUnitType(dataArray, nalUnitOffset);

      // This is the number of bytes from the current offset to the start of the next NAL unit.
      // It may be negative if the NAL unit started in the previously consumed data.
      int lengthToNalUnit = nalUnitOffset - offset;
      if (lengthToNalUnit > 0) {
        nalUnitData(dataArray, offset, nalUnitOffset);
      }
      int bytesWrittenPastPosition = limit - nalUnitOffset;
      long absolutePosition = totalBytesWritten - bytesWrittenPastPosition;
      // Indicate the end of the previous NAL unit. If the length to the start of the next unit
      // is negative then we wrote too many bytes to the NAL buffers. Discard the excess bytes
      // when notifying that the unit has ended.
      endNalUnit(absolutePosition, bytesWrittenPastPosition,
          lengthToNalUnit < 0 ? -lengthToNalUnit : 0, pesTimeUs);
      // Indicate the start of the next NAL unit.
      startNalUnit(absolutePosition, nalUnitType, pesTimeUs);
      // Continue scanning the data.
      offset = nalUnitOffset + 3;
    }
  }
}
项目:ExoPlayer-Demo    文件:H264Reader.java   
private static ParsableBitArray unescape(NalUnitTargetBuffer buffer) {
  int length = NalUnitUtil.unescapeStream(buffer.nalData, buffer.nalLength);
  ParsableBitArray bitArray = new ParsableBitArray(buffer.nalData, length);
  bitArray.skipBits(32); // NAL header
  return bitArray;
}
项目:ExoPlayer-Demo    文件:H264Reader.java   
public void putSps(NalUnitUtil.SpsData spsData) {
  sps.append(spsData.seqParameterSetId, spsData);
}
项目:ExoPlayer-Demo    文件:H264Reader.java   
public void putPps(NalUnitUtil.PpsData ppsData) {
  pps.append(ppsData.picParameterSetId, ppsData);
}
项目:ExoPlayer-Demo    文件:H265Reader.java   
@Override
public void consume(ParsableByteArray data) {
  while (data.bytesLeft() > 0) {
    int offset = data.getPosition();
    int limit = data.limit();
    byte[] dataArray = data.data;

    // Append the data to the buffer.
    totalBytesWritten += data.bytesLeft();
    output.sampleData(data, data.bytesLeft());

    // Scan the appended data, processing NAL units as they are encountered
    while (offset < limit) {
      int nalUnitOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);

      if (nalUnitOffset == limit) {
        // We've scanned to the end of the data without finding the start of another NAL unit.
        nalUnitData(dataArray, offset, limit);
        return;
      }

      // We've seen the start of a NAL unit of the following type.
      int nalUnitType = NalUnitUtil.getH265NalUnitType(dataArray, nalUnitOffset);

      // This is the number of bytes from the current offset to the start of the next NAL unit.
      // It may be negative if the NAL unit started in the previously consumed data.
      int lengthToNalUnit = nalUnitOffset - offset;
      if (lengthToNalUnit > 0) {
        nalUnitData(dataArray, offset, nalUnitOffset);
      }

      int bytesWrittenPastPosition = limit - nalUnitOffset;
      long absolutePosition = totalBytesWritten - bytesWrittenPastPosition;
      // Indicate the end of the previous NAL unit. If the length to the start of the next unit
      // is negative then we wrote too many bytes to the NAL buffers. Discard the excess bytes
      // when notifying that the unit has ended.
      endNalUnit(absolutePosition, bytesWrittenPastPosition,
          lengthToNalUnit < 0 ? -lengthToNalUnit : 0, pesTimeUs);
      // Indicate the start of the next NAL unit.
      startNalUnit(absolutePosition, bytesWrittenPastPosition, nalUnitType, pesTimeUs);
      // Continue scanning the data.
      offset = nalUnitOffset + 3;
    }
  }
}
项目:ExoPlayer-Demo    文件:VideoTagPayloadReader.java   
/**
 * @param output A {@link TrackOutput} to which samples should be written.
 */
public VideoTagPayloadReader(TrackOutput output) {
  super(output);
  nalStartCode = new ParsableByteArray(NalUnitUtil.NAL_START_CODE);
  nalLength = new ParsableByteArray(4);
}
项目:ExoPlayer    文件:H264Reader.java   
@Override
public void consume(ParsableByteArray data, long pesTimeUs, boolean startOfPacket) {
  while (data.bytesLeft() > 0) {
    int offset = data.getPosition();
    int limit = data.limit();
    byte[] dataArray = data.data;

    // Append the data to the buffer.
    totalBytesWritten += data.bytesLeft();
    output.sampleData(data, data.bytesLeft());

    // Scan the appended data, processing NAL units as they are encountered
    while (offset < limit) {
      int nextNalUnitOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);
      if (nextNalUnitOffset < limit) {
        // We've seen the start of a NAL unit.

        // This is the length to the start of the unit. It may be negative if the NAL unit
        // actually started in previously consumed data.
        int lengthToNalUnit = nextNalUnitOffset - offset;
        if (lengthToNalUnit > 0) {
          feedNalUnitTargetBuffersData(dataArray, offset, nextNalUnitOffset);
        }

        int nalUnitType = NalUnitUtil.getNalUnitType(dataArray, nextNalUnitOffset);
        int bytesWrittenPastNalUnit = limit - nextNalUnitOffset;
        switch (nalUnitType) {
          case NAL_UNIT_TYPE_IDR:
            isKeyframe = true;
            break;
          case NAL_UNIT_TYPE_AUD:
            if (foundFirstSample) {
              if (ifrParserBuffer != null && ifrParserBuffer.isCompleted()) {
                int sliceType = ifrParserBuffer.getSliceType();
                isKeyframe |= (sliceType == FRAME_TYPE_I || sliceType == FRAME_TYPE_ALL_I);
                ifrParserBuffer.reset();
              }
              if (isKeyframe && !hasOutputFormat && sps.isCompleted() && pps.isCompleted()) {
                parseMediaFormat(sps, pps);
              }
              int flags = isKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
              int size = (int) (totalBytesWritten - samplePosition) - bytesWrittenPastNalUnit;
              output.sampleMetadata(sampleTimeUs, flags, size, bytesWrittenPastNalUnit, null);
            }
            foundFirstSample = true;
            samplePosition = totalBytesWritten - bytesWrittenPastNalUnit;
            sampleTimeUs = pesTimeUs;
            isKeyframe = false;
            break;
        }

        // If the length to the start of the unit is negative then we wrote too many bytes to the
        // NAL buffers. Discard the excess bytes when notifying that the unit has ended.
        feedNalUnitTargetEnd(pesTimeUs, lengthToNalUnit < 0 ? -lengthToNalUnit : 0);
        // Notify the start of the next NAL unit.
        feedNalUnitTargetBuffersStart(nalUnitType);
        // Continue scanning the data.
        offset = nextNalUnitOffset + 3;
      } else {
        feedNalUnitTargetBuffersData(dataArray, offset, limit);
        offset = limit;
      }
    }
  }
}
项目:ExoPlayer    文件:H265Reader.java   
@Override
public void consume(ParsableByteArray data, long pesTimeUs, boolean startOfPacket) {
  while (data.bytesLeft() > 0) {
    int offset = data.getPosition();
    int limit = data.limit();
    byte[] dataArray = data.data;

    // Append the data to the buffer.
    totalBytesWritten += data.bytesLeft();
    output.sampleData(data, data.bytesLeft());

    // Scan the appended data, processing NAL units as they are encountered
    while (offset < limit) {
      int nextNalUnitOffset = NalUnitUtil.findNalUnit(dataArray, offset, limit, prefixFlags);
      if (nextNalUnitOffset < limit) {
        // We've seen the start of a NAL unit.

        // This is the length to the start of the unit. It may be negative if the NAL unit
        // actually started in previously consumed data.
        int lengthToNalUnit = nextNalUnitOffset - offset;
        if (lengthToNalUnit > 0) {
          feedNalUnitTargetBuffersData(dataArray, offset, nextNalUnitOffset);
        }

        int nalUnitType = NalUnitUtil.getH265NalUnitType(dataArray, nextNalUnitOffset);
        int bytesWrittenPastNalUnit = limit - nextNalUnitOffset;
        if (isFirstSliceSegmentInPic(dataArray, nextNalUnitOffset)) {
          if (foundFirstSample) {
            if (isKeyframe && !hasOutputFormat && vps.isCompleted() && sps.isCompleted()
                && pps.isCompleted()) {
              parseMediaFormat(vps, sps, pps);
            }
            int flags = isKeyframe ? C.SAMPLE_FLAG_SYNC : 0;
            int size = (int) (totalBytesWritten - samplePosition) - bytesWrittenPastNalUnit;
            output.sampleMetadata(sampleTimeUs, flags, size, bytesWrittenPastNalUnit, null);
          }
          foundFirstSample = true;
          samplePosition = totalBytesWritten - bytesWrittenPastNalUnit;
          sampleTimeUs = pesTimeUs;
          isKeyframe = isRandomAccessPoint(nalUnitType);
        }

        // If the length to the start of the unit is negative then we wrote too many bytes to the
        // NAL buffers. Discard the excess bytes when notifying that the unit has ended.
        feedNalUnitTargetEnd(pesTimeUs, lengthToNalUnit < 0 ? -lengthToNalUnit : 0);
        // Notify the start of the next NAL unit.
        feedNalUnitTargetBuffersStart(nalUnitType);
        // Continue scanning the data.
        offset = nextNalUnitOffset + 3;
      } else {
        feedNalUnitTargetBuffersData(dataArray, offset, limit);
        offset = limit;
      }
    }
  }
}
项目:miku    文件:H265Reader.java   
/**
 * Returns whether the NAL unit in {@code data} starting at {@code offset} contains the first
 * slice in a picture.
 *
 * @param data The data to read.
 * @param offset The start offset of a NAL unit. Must lie between {@code -3} (inclusive) and
 *     {@code data.length - 3} (exclusive).
 * @return Whether the NAL unit contains the first slice in a picture.
 */
public static boolean isFirstSliceSegmentInPic(byte[] data, int offset) {
  int nalUnitType = NalUnitUtil.getH265NalUnitType(data, offset);
  // Check the flag in NAL units that contain a slice_segment_layer_rbsp RBSP.
  if ((nalUnitType <= RASL_R) || (nalUnitType >= BLA_W_LP && nalUnitType <= CRA_NUT)) {
    return (data[offset + 5] & 0x80) != 0;
  }
  return false;
}
项目:ExoPlayer    文件:H265Reader.java   
/**
 * Returns whether the NAL unit in {@code data} starting at {@code offset} contains the first
 * slice in a picture.
 *
 * @param data The data to read.
 * @param offset The start offset of a NAL unit. Must lie between {@code -3} (inclusive) and
 *     {@code data.length - 3} (exclusive).
 * @return Whether the NAL unit contains the first slice in a picture.
 */
public static boolean isFirstSliceSegmentInPic(byte[] data, int offset) {
  int nalUnitType = NalUnitUtil.getH265NalUnitType(data, offset);
  // Check the flag in NAL units that contain a slice_segment_layer_rbsp RBSP.
  if ((nalUnitType <= RASL_R) || (nalUnitType >= BLA_W_LP && nalUnitType <= CRA_NUT)) {
    return (data[offset + 5] & 0x80) != 0;
  }
  return false;
}