Search in sources :

Example 11 with Format

use of com.google.android.exoplayer2.Format 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 12 with Format

use of com.google.android.exoplayer2.Format in project ExoPlayer by google.

the class SimpleDecoderAudioRenderer method drainOutputBuffer.

private boolean drainOutputBuffer() throws ExoPlaybackException, AudioDecoderException, AudioTrack.ConfigurationException, AudioTrack.InitializationException, AudioTrack.WriteException {
    if (outputBuffer == null) {
        outputBuffer = decoder.dequeueOutputBuffer();
        if (outputBuffer == null) {
            return false;
        }
        decoderCounters.skippedOutputBufferCount += outputBuffer.skippedOutputBufferCount;
    }
    if (outputBuffer.isEndOfStream()) {
        if (decoderReinitializationState == REINITIALIZATION_STATE_WAIT_END_OF_STREAM) {
            // We're waiting to re-initialize the decoder, and have now processed all final buffers.
            releaseDecoder();
            maybeInitDecoder();
            // The audio track may need to be recreated once the new output format is known.
            audioTrackNeedsConfigure = true;
        } else {
            outputBuffer.release();
            outputBuffer = null;
            processEndOfStream();
        }
        return false;
    }
    if (audioTrackNeedsConfigure) {
        Format outputFormat = getOutputFormat();
        audioTrack.configure(outputFormat.sampleMimeType, outputFormat.channelCount, outputFormat.sampleRate, outputFormat.pcmEncoding, 0);
        audioTrackNeedsConfigure = false;
    }
    if (audioTrack.handleBuffer(outputBuffer.data, outputBuffer.timeUs)) {
        decoderCounters.renderedOutputBufferCount++;
        outputBuffer.release();
        outputBuffer = null;
        return true;
    }
    return false;
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 13 with Format

use of com.google.android.exoplayer2.Format in project ExoPlayer by google.

the class OfflineLicenseHelper method download.

/**
   * Downloads an offline license.
   *
   * @param dataSource The {@link HttpDataSource} to be used for download.
   * @param dashManifest The {@link DashManifest} of the DASH content.
   * @return The downloaded offline license key set id.
   * @throws IOException If an error occurs reading data from the stream.
   * @throws InterruptedException If the thread has been interrupted.
   * @throws DrmSessionException Thrown when there is an error during DRM session.
   */
public byte[] download(HttpDataSource dataSource, DashManifest dashManifest) throws IOException, InterruptedException, DrmSessionException {
    // as per DASH IF Interoperability Recommendations V3.0, 7.5.3.
    if (dashManifest.getPeriodCount() < 1) {
        return null;
    }
    Period period = dashManifest.getPeriod(0);
    int adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_VIDEO);
    if (adaptationSetIndex == C.INDEX_UNSET) {
        adaptationSetIndex = period.getAdaptationSetIndex(C.TRACK_TYPE_AUDIO);
        if (adaptationSetIndex == C.INDEX_UNSET) {
            return null;
        }
    }
    AdaptationSet adaptationSet = period.adaptationSets.get(adaptationSetIndex);
    if (adaptationSet.representations.isEmpty()) {
        return null;
    }
    Representation representation = adaptationSet.representations.get(0);
    DrmInitData drmInitData = representation.format.drmInitData;
    if (drmInitData == null) {
        Format sampleFormat = DashUtil.loadSampleFormat(dataSource, representation);
        if (sampleFormat != null) {
            drmInitData = sampleFormat.drmInitData;
        }
        if (drmInitData == null) {
            return null;
        }
    }
    blockingKeyRequest(DefaultDrmSessionManager.MODE_DOWNLOAD, null, drmInitData);
    return drmSessionManager.getOfflineLicenseKeySetId();
}
Also used : Format(com.google.android.exoplayer2.Format) Period(com.google.android.exoplayer2.source.dash.manifest.Period) AdaptationSet(com.google.android.exoplayer2.source.dash.manifest.AdaptationSet) Representation(com.google.android.exoplayer2.source.dash.manifest.Representation)

Example 14 with Format

use of com.google.android.exoplayer2.Format in project ExoPlayer by google.

the class DefaultTrackOutput method format.

@Override
public void format(Format format) {
    Format adjustedFormat = getAdjustedSampleFormat(format, sampleOffsetUs);
    boolean formatChanged = infoQueue.format(adjustedFormat);
    lastUnadjustedFormat = format;
    pendingFormatAdjustment = false;
    if (upstreamFormatChangeListener != null && formatChanged) {
        upstreamFormatChangeListener.onUpstreamFormatChanged(adjustedFormat);
    }
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 15 with Format

use of com.google.android.exoplayer2.Format 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)

Aggregations

Format (com.google.android.exoplayer2.Format)44 Point (android.graphics.Point)8 ArrayList (java.util.ArrayList)8 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)7 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)5 SuppressLint (android.annotation.SuppressLint)4 MediaFormat (android.media.MediaFormat)4 ParserException (com.google.android.exoplayer2.ParserException)4 DrmInitData (com.google.android.exoplayer2.drm.DrmInitData)4 ParsableByteArray (com.google.android.exoplayer2.util.ParsableByteArray)4 TrackOutput (com.google.android.exoplayer2.extractor.TrackOutput)3 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)3 Representation (com.google.android.exoplayer2.source.dash.manifest.Representation)3 SchemeData (com.google.android.exoplayer2.drm.DrmInitData.SchemeData)2 MediaCodecInfo (com.google.android.exoplayer2.mediacodec.MediaCodecInfo)2 Metadata (com.google.android.exoplayer2.metadata.Metadata)2 ContainerMediaChunk (com.google.android.exoplayer2.source.chunk.ContainerMediaChunk)2 AdaptationSet (com.google.android.exoplayer2.source.dash.manifest.AdaptationSet)2 RangedUri (com.google.android.exoplayer2.source.dash.manifest.RangedUri)2 SingleSegmentBase (com.google.android.exoplayer2.source.dash.manifest.SegmentBase.SingleSegmentBase)2