Search in sources :

Example 11 with ParsableByteArray

use of com.google.android.exoplayer2.util.ParsableByteArray in project ExoPlayer by google.

the class AudioTagPayloadReader method parseHeader.

@Override
protected boolean parseHeader(ParsableByteArray data) throws UnsupportedFormatException {
    if (!hasParsedAudioDataHeader) {
        int header = data.readUnsignedByte();
        audioFormat = (header >> 4) & 0x0F;
        // TODO: Add support for MP3.
        if (audioFormat == AUDIO_FORMAT_ALAW || audioFormat == AUDIO_FORMAT_ULAW) {
            String type = audioFormat == AUDIO_FORMAT_ALAW ? MimeTypes.AUDIO_ALAW : MimeTypes.AUDIO_ULAW;
            int pcmEncoding = (header & 0x01) == 1 ? C.ENCODING_PCM_16BIT : C.ENCODING_PCM_8BIT;
            Format format = Format.createAudioSampleFormat(null, type, null, Format.NO_VALUE, Format.NO_VALUE, 1, 8000, pcmEncoding, null, null, 0, null);
            output.format(format);
            hasOutputFormat = true;
        } else if (audioFormat != AUDIO_FORMAT_AAC) {
            throw new UnsupportedFormatException("Audio format not supported: " + audioFormat);
        }
        hasParsedAudioDataHeader = true;
    } else {
        // Skip header if it was parsed previously.
        data.skipBytes(1);
    }
    return true;
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 12 with ParsableByteArray

use of com.google.android.exoplayer2.util.ParsableByteArray in project ExoPlayer by google.

the class VideoTagPayloadReader method parsePayload.

@Override
protected void parsePayload(ParsableByteArray data, long timeUs) throws ParserException {
    int packetType = data.readUnsignedByte();
    int compositionTimeMs = data.readUnsignedInt24();
    timeUs += compositionTimeMs * 1000L;
    // Parse avc sequence header in case this was not done before.
    if (packetType == AVC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) {
        ParsableByteArray videoSequence = new ParsableByteArray(new byte[data.bytesLeft()]);
        data.readBytes(videoSequence.data, 0, data.bytesLeft());
        AvcConfig avcConfig = AvcConfig.parse(videoSequence);
        nalUnitLengthFieldLength = avcConfig.nalUnitLengthFieldLength;
        // Construct and output the format.
        Format format = Format.createVideoSampleFormat(null, MimeTypes.VIDEO_H264, null, Format.NO_VALUE, Format.NO_VALUE, avcConfig.width, avcConfig.height, Format.NO_VALUE, avcConfig.initializationData, Format.NO_VALUE, avcConfig.pixelWidthAspectRatio, null);
        output.format(format);
        hasOutputFormat = true;
    } else if (packetType == AVC_PACKET_TYPE_AVC_NALU) {
        // TODO: Deduplicate with Mp4Extractor.
        // Zero the top three bytes of the array that we'll use to decode nal unit lengths, in case
        // they're only 1 or 2 bytes long.
        byte[] nalLengthData = nalLength.data;
        nalLengthData[0] = 0;
        nalLengthData[1] = 0;
        nalLengthData[2] = 0;
        int nalUnitLengthFieldLengthDiff = 4 - nalUnitLengthFieldLength;
        // NAL units are length delimited, but the decoder requires start code delimited units.
        // Loop until we've written the sample to the track output, replacing length delimiters with
        // start codes as we encounter them.
        int bytesWritten = 0;
        int bytesToWrite;
        while (data.bytesLeft() > 0) {
            // Read the NAL length so that we know where we find the next one.
            data.readBytes(nalLength.data, nalUnitLengthFieldLengthDiff, nalUnitLengthFieldLength);
            nalLength.setPosition(0);
            bytesToWrite = nalLength.readUnsignedIntToInt();
            // Write a start code for the current NAL unit.
            nalStartCode.setPosition(0);
            output.sampleData(nalStartCode, 4);
            bytesWritten += 4;
            // Write the payload of the NAL unit.
            output.sampleData(data, bytesToWrite);
            bytesWritten += bytesToWrite;
        }
        output.sampleMetadata(timeUs, frameType == VIDEO_FRAME_KEYFRAME ? C.BUFFER_FLAG_KEY_FRAME : 0, bytesWritten, 0, null);
    }
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) Format(com.google.android.exoplayer2.Format) AvcConfig(com.google.android.exoplayer2.video.AvcConfig)

Example 13 with ParsableByteArray

use of com.google.android.exoplayer2.util.ParsableByteArray in project ExoPlayer by google.

the class StreamReader method readPayload.

private int readPayload(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException {
    long position = oggSeeker.read(input);
    if (position >= 0) {
        seekPosition.position = position;
        return Extractor.RESULT_SEEK;
    } else if (position < -1) {
        onSeekEnd(-(position + 2));
    }
    if (!seekMapSet) {
        SeekMap seekMap = oggSeeker.createSeekMap();
        extractorOutput.seekMap(seekMap);
        seekMapSet = true;
    }
    if (lengthOfReadPacket > 0 || oggPacket.populate(input)) {
        lengthOfReadPacket = 0;
        ParsableByteArray payload = oggPacket.getPayload();
        long granulesInPacket = preparePayload(payload);
        if (granulesInPacket >= 0 && currentGranule + granulesInPacket >= targetGranule) {
            // calculate time and send payload data to codec
            long timeUs = convertGranuleToTime(currentGranule);
            trackOutput.sampleData(payload, payload.limit());
            trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, payload.limit(), 0, null);
            targetGranule = -1;
        }
        currentGranule += granulesInPacket;
    } else {
        state = STATE_END_OF_INPUT;
        return Extractor.RESULT_END_OF_INPUT;
    }
    return Extractor.RESULT_CONTINUE;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) SeekMap(com.google.android.exoplayer2.extractor.SeekMap)

Example 14 with ParsableByteArray

use of com.google.android.exoplayer2.util.ParsableByteArray in project ExoPlayer by google.

the class DefaultTsPayloadReaderFactory method buildSeiReader.

/**
   * If {@link #FLAG_OVERRIDE_CAPTION_DESCRIPTORS} is set, returns a {@link SeiReader} for
   * {@link #closedCaptionFormats}. If unset, parses the PMT descriptor information and returns a
   * {@link SeiReader} for the declared formats, or {@link #closedCaptionFormats} if the descriptor
   * is not present.
   *
   * @param esInfo The {@link EsInfo} passed to {@link #createPayloadReader(int, EsInfo)}.
   * @return A {@link SeiReader} for closed caption tracks.
   */
private SeiReader buildSeiReader(EsInfo esInfo) {
    if (isSet(FLAG_OVERRIDE_CAPTION_DESCRIPTORS)) {
        return new SeiReader(closedCaptionFormats);
    }
    ParsableByteArray scratchDescriptorData = new ParsableByteArray(esInfo.descriptorBytes);
    List<Format> closedCaptionFormats = this.closedCaptionFormats;
    while (scratchDescriptorData.bytesLeft() > 0) {
        int descriptorTag = scratchDescriptorData.readUnsignedByte();
        int descriptorLength = scratchDescriptorData.readUnsignedByte();
        int nextDescriptorPosition = scratchDescriptorData.getPosition() + descriptorLength;
        if (descriptorTag == DESCRIPTOR_TAG_CAPTION_SERVICE) {
            // Note: see ATSC A/65 for detailed information about the caption service descriptor.
            closedCaptionFormats = new ArrayList<>();
            int numberOfServices = scratchDescriptorData.readUnsignedByte() & 0x1F;
            for (int i = 0; i < numberOfServices; i++) {
                String language = scratchDescriptorData.readString(3);
                int captionTypeByte = scratchDescriptorData.readUnsignedByte();
                boolean isDigital = (captionTypeByte & 0x80) != 0;
                String mimeType;
                int accessibilityChannel;
                if (isDigital) {
                    mimeType = MimeTypes.APPLICATION_CEA708;
                    accessibilityChannel = captionTypeByte & 0x3F;
                } else {
                    mimeType = MimeTypes.APPLICATION_CEA608;
                    accessibilityChannel = 1;
                }
                closedCaptionFormats.add(Format.createTextSampleFormat(null, mimeType, null, Format.NO_VALUE, 0, language, accessibilityChannel, null));
                // Skip easy_reader(1), wide_aspect_ratio(1), reserved(14).
                scratchDescriptorData.skipBytes(2);
            }
        } else {
        // Unknown descriptor. Ignore.
        }
        scratchDescriptorData.setPosition(nextDescriptorPosition);
    }
    return new SeiReader(closedCaptionFormats);
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) Format(com.google.android.exoplayer2.Format)

Example 15 with ParsableByteArray

use of com.google.android.exoplayer2.util.ParsableByteArray in project ExoPlayer by google.

the class VorbisUtilTest method testVerifyVorbisHeaderCapturePatternQuiteInvalidPatternQuite.

public void testVerifyVorbisHeaderCapturePatternQuiteInvalidPatternQuite() throws ParserException {
    ParsableByteArray header = new ParsableByteArray(new byte[] { 0x01, 'x', 'v', 'o', 'r', 'b', 'i', 's' });
    assertFalse(VorbisUtil.verifyVorbisHeaderCapturePattern(0x01, header, true));
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray)

Aggregations

ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)48 ParserException (com.google.android.exoplayer2.ParserException)11 Format (com.google.android.exoplayer2.Format)6 ArrayList (java.util.ArrayList)4 SeekMap (com.google.android.exoplayer2.extractor.SeekMap)3 Metadata (com.google.android.exoplayer2.metadata.Metadata)3 TrackOutput (com.google.android.exoplayer2.extractor.TrackOutput)2 ContainerAtom (com.google.android.exoplayer2.extractor.mp4.Atom.ContainerAtom)2 FlacStreamInfo (com.google.android.exoplayer2.util.FlacStreamInfo)2 AvcConfig (com.google.android.exoplayer2.video.AvcConfig)2 ByteBuffer (java.nio.ByteBuffer)2 Matcher (java.util.regex.Matcher)2 Spanned (android.text.Spanned)1 ChunkIndex (com.google.android.exoplayer2.extractor.ChunkIndex)1 MpegAudioHeader (com.google.android.exoplayer2.extractor.MpegAudioHeader)1 LeafAtom (com.google.android.exoplayer2.extractor.mp4.Atom.LeafAtom)1 TrackIdGenerator (com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator)1 CommentFrame (com.google.android.exoplayer2.metadata.id3.CommentFrame)1 TextInformationFrame (com.google.android.exoplayer2.metadata.id3.TextInformationFrame)1 FakeExtractorOutput (com.google.android.exoplayer2.testutil.FakeExtractorOutput)1