/**
  * Continues a read from the provided {@code source} into a given {@code target}. It's assumed
  * that the data should be written into {@code target} starting from an offset of zero.
  *
  * @param source The source from which to read.
  * @param target The target into which data is to be read, or {@code null} to skip.
  * @param targetLength The target length of the read.
  * @return Whether the target length has been reached.
  */
 private boolean continueRead(ParsableByteArray source, byte[] target, int targetLength) {
   int bytesToRead = Math.min(source.bytesLeft(), targetLength - bytesRead);
   if (bytesToRead <= 0) {
     return true;
   } else if (target == null) {
     source.skip(bytesToRead);
   } else {
     source.readBytes(target, bytesRead, bytesToRead);
   }
   bytesRead += bytesToRead;
   return bytesRead == targetLength;
 }
  private static void parseSenc(ParsableByteArray senc, int offset, TrackFragment out)
      throws ParserException {
    senc.setPosition(Atom.HEADER_SIZE + offset);
    int fullAtom = senc.readInt();
    int flags = Atom.parseFullAtomFlags(fullAtom);

    if ((flags & 0x01 /* override_track_encryption_box_parameters */) != 0) {
      // TODO: Implement this.
      throw new ParserException("Overriding TrackEncryptionBox parameters is unsupported.");
    }

    boolean subsampleEncryption = (flags & 0x02 /* use_subsample_encryption */) != 0;
    int sampleCount = senc.readUnsignedIntToInt();
    if (sampleCount != out.length) {
      throw new ParserException("Length mismatch: " + sampleCount + ", " + out.length);
    }

    Arrays.fill(out.sampleHasSubsampleEncryptionTable, 0, sampleCount, subsampleEncryption);
    out.initEncryptionData(senc.bytesLeft());
    out.fillEncryptionData(senc);
  }
示例#3
0
 @Override
 public void consume(ParsableByteArray data) {
   if (!writingSample) {
     return;
   }
   int bytesAvailable = data.bytesLeft();
   if (sampleBytesRead < ID3_HEADER_SIZE) {
     // We're still reading the ID3 header.
     int headerBytesAvailable = Math.min(bytesAvailable, ID3_HEADER_SIZE - sampleBytesRead);
     System.arraycopy(
         data.data, data.getPosition(), id3Header.data, sampleBytesRead, headerBytesAvailable);
     if (sampleBytesRead + headerBytesAvailable == ID3_HEADER_SIZE) {
       // We've finished reading the ID3 header. Extract the sample size.
       id3Header.setPosition(6); // 'ID3' (3) + version (2) + flags (1)
       sampleSize = ID3_HEADER_SIZE + id3Header.readSynchSafeInt();
     }
   }
   // Write data to the output.
   output.sampleData(data, bytesAvailable);
   sampleBytesRead += bytesAvailable;
 }
    @Override
    public void consume(ParsableByteArray data, boolean payloadUnitStartIndicator) {
      if (payloadUnitStartIndicator) {
        switch (state) {
          case STATE_FINDING_HEADER:
          case STATE_READING_HEADER:
            // Expected.
            break;
          case STATE_READING_HEADER_EXTENSION:
            Log.w(TAG, "Unexpected start indicator reading extended header");
            break;
          case STATE_READING_BODY:
            // If payloadSize == -1 then the length of the previous packet was unspecified, and so
            // we only know that it's finished now that we've seen the start of the next one. This
            // is expected. If payloadSize != -1, then the length of the previous packet was known,
            // but we didn't receive that amount of data. This is not expected.
            if (payloadSize != -1) {
              Log.w(TAG, "Unexpected start indicator: expected " + payloadSize + " more bytes");
            }
            // Either way, if the body was started, notify the reader that it has now finished.
            if (bodyStarted) {
              pesPayloadReader.packetFinished();
            }
            break;
        }
        setState(STATE_READING_HEADER);
      }

      while (data.bytesLeft() > 0) {
        switch (state) {
          case STATE_FINDING_HEADER:
            data.skip(data.bytesLeft());
            break;
          case STATE_READING_HEADER:
            if (continueRead(data, pesScratch.getData(), HEADER_SIZE)) {
              setState(parseHeader() ? STATE_READING_HEADER_EXTENSION : STATE_FINDING_HEADER);
            }
            break;
          case STATE_READING_HEADER_EXTENSION:
            int readLength = Math.min(MAX_HEADER_EXTENSION_SIZE, extendedHeaderLength);
            // Read as much of the extended header as we're interested in, and skip the rest.
            if (continueRead(data, pesScratch.getData(), readLength)
                && continueRead(data, null, extendedHeaderLength)) {
              parseHeaderExtension();
              bodyStarted = false;
              setState(STATE_READING_BODY);
            }
            break;
          case STATE_READING_BODY:
            readLength = data.bytesLeft();
            int padding = payloadSize == -1 ? 0 : readLength - payloadSize;
            if (padding > 0) {
              readLength -= padding;
              data.setLimit(data.getPosition() + readLength);
            }
            pesPayloadReader.consume(data, timeUs, !bodyStarted);
            bodyStarted = true;
            if (payloadSize != -1) {
              payloadSize -= readLength;
              if (payloadSize == 0) {
                pesPayloadReader.packetFinished();
                setState(STATE_READING_HEADER);
              }
            }
            break;
        }
      }
    }