Search in sources :

Example 51 with Format

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

the class WavExtractor method read.

@Override
public int read(ExtractorInput input, PositionHolder seekPosition) throws IOException, InterruptedException {
    if (wavHeader == null) {
        wavHeader = WavHeaderReader.peek(input);
        if (wavHeader == null) {
            // Should only happen if the media wasn't sniffed.
            throw new ParserException("Unsupported or unrecognized wav header.");
        }
        Format format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_RAW, null, wavHeader.getBitrate(), MAX_INPUT_SIZE, wavHeader.getNumChannels(), wavHeader.getSampleRateHz(), wavHeader.getEncoding(), null, null, 0, null);
        trackOutput.format(format);
        bytesPerFrame = wavHeader.getBytesPerFrame();
    }
    if (!wavHeader.hasDataBounds()) {
        WavHeaderReader.skipToData(input, wavHeader);
        extractorOutput.seekMap(this);
    }
    int bytesAppended = trackOutput.sampleData(input, MAX_INPUT_SIZE - pendingBytes, true);
    if (bytesAppended != RESULT_END_OF_INPUT) {
        pendingBytes += bytesAppended;
    }
    // Samples must consist of a whole number of frames.
    int pendingFrames = pendingBytes / bytesPerFrame;
    if (pendingFrames > 0) {
        long timeUs = wavHeader.getTimeUs(input.getPosition() - pendingBytes);
        int size = pendingFrames * bytesPerFrame;
        pendingBytes -= size;
        trackOutput.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, size, pendingBytes, null);
    }
    return bytesAppended == RESULT_END_OF_INPUT ? RESULT_END_OF_INPUT : RESULT_CONTINUE;
}
Also used : ParserException(com.google.android.exoplayer2.ParserException) Format(com.google.android.exoplayer2.Format)

Example 52 with Format

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

the class MediaCodecRenderer method maybeInitCodec.

@SuppressWarnings("deprecation")
protected final void maybeInitCodec() throws ExoPlaybackException {
    if (!shouldInitCodec()) {
        return;
    }
    drmSession = pendingDrmSession;
    String mimeType = format.sampleMimeType;
    MediaCrypto mediaCrypto = null;
    boolean drmSessionRequiresSecureDecoder = false;
    if (drmSession != null) {
        @DrmSession.State int drmSessionState = drmSession.getState();
        if (drmSessionState == DrmSession.STATE_ERROR) {
            throw ExoPlaybackException.createForRenderer(drmSession.getError(), getIndex());
        } else if (drmSessionState == DrmSession.STATE_OPENED || drmSessionState == DrmSession.STATE_OPENED_WITH_KEYS) {
            mediaCrypto = drmSession.getMediaCrypto().getWrappedMediaCrypto();
            drmSessionRequiresSecureDecoder = drmSession.requiresSecureDecoderComponent(mimeType);
        } else {
            // The drm session isn't open yet.
            return;
        }
    }
    MediaCodecInfo decoderInfo = null;
    try {
        decoderInfo = getDecoderInfo(mediaCodecSelector, format, drmSessionRequiresSecureDecoder);
        if (decoderInfo == null && drmSessionRequiresSecureDecoder) {
            // The drm session indicates that a secure decoder is required, but the device does not have
            // one. Assuming that supportsFormat indicated support for the media being played, we know
            // that it does not require a secure output path. Most CDM implementations allow playback to
            // proceed with a non-secure decoder in this case, so we try our luck.
            decoderInfo = getDecoderInfo(mediaCodecSelector, format, false);
            if (decoderInfo != null) {
                Log.w(TAG, "Drm session requires secure decoder for " + mimeType + ", but " + "no secure decoder available. Trying to proceed with " + decoderInfo.name + ".");
            }
        }
    } catch (DecoderQueryException e) {
        throwDecoderInitError(new DecoderInitializationException(format, e, drmSessionRequiresSecureDecoder, DecoderInitializationException.DECODER_QUERY_ERROR));
    }
    if (decoderInfo == null) {
        throwDecoderInitError(new DecoderInitializationException(format, null, drmSessionRequiresSecureDecoder, DecoderInitializationException.NO_SUITABLE_DECODER_ERROR));
    }
    String codecName = decoderInfo.name;
    codecIsAdaptive = decoderInfo.adaptive;
    codecNeedsDiscardToSpsWorkaround = codecNeedsDiscardToSpsWorkaround(codecName, format);
    codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
    codecNeedsAdaptationWorkaround = codecNeedsAdaptationWorkaround(codecName);
    codecNeedsEosPropagationWorkaround = codecNeedsEosPropagationWorkaround(codecName);
    codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
    codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
    codecNeedsMonoChannelCountWorkaround = codecNeedsMonoChannelCountWorkaround(codecName, format);
    try {
        long codecInitializingTimestamp = SystemClock.elapsedRealtime();
        TraceUtil.beginSection("createCodec:" + codecName);
        codec = MediaCodec.createByCodecName(codecName);
        TraceUtil.endSection();
        TraceUtil.beginSection("configureCodec");
        configureCodec(decoderInfo, codec, format, mediaCrypto);
        TraceUtil.endSection();
        TraceUtil.beginSection("startCodec");
        codec.start();
        TraceUtil.endSection();
        long codecInitializedTimestamp = SystemClock.elapsedRealtime();
        onCodecInitialized(codecName, codecInitializedTimestamp, codecInitializedTimestamp - codecInitializingTimestamp);
        inputBuffers = codec.getInputBuffers();
        outputBuffers = codec.getOutputBuffers();
    } catch (Exception e) {
        throwDecoderInitError(new DecoderInitializationException(format, e, drmSessionRequiresSecureDecoder, codecName));
    }
    codecHotswapDeadlineMs = getState() == STATE_STARTED ? (SystemClock.elapsedRealtime() + MAX_CODEC_HOTSWAP_TIME_MS) : C.TIME_UNSET;
    inputIndex = C.INDEX_UNSET;
    outputIndex = C.INDEX_UNSET;
    waitingForFirstSyncFrame = true;
    decoderCounters.decoderInitCount++;
}
Also used : DecoderQueryException(com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException) ExoPlaybackException(com.google.android.exoplayer2.ExoPlaybackException) CodecException(android.media.MediaCodec.CodecException) CryptoException(android.media.MediaCodec.CryptoException) DecoderQueryException(com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException) FrameworkMediaCrypto(com.google.android.exoplayer2.drm.FrameworkMediaCrypto) MediaCrypto(android.media.MediaCrypto)

Example 53 with Format

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

the class HlsSampleStreamWrapper method readData.

/* package */
int readData(int group, FormatHolder formatHolder, DecoderInputBuffer buffer, boolean requireFormat) {
    if (isPendingReset()) {
        return C.RESULT_NOTHING_READ;
    }
    while (mediaChunks.size() > 1 && finishedReadingChunk(mediaChunks.getFirst())) {
        mediaChunks.removeFirst();
    }
    HlsMediaChunk currentChunk = mediaChunks.getFirst();
    Format trackFormat = currentChunk.trackFormat;
    if (!trackFormat.equals(downstreamTrackFormat)) {
        eventDispatcher.downstreamFormatChanged(trackType, trackFormat, currentChunk.trackSelectionReason, currentChunk.trackSelectionData, currentChunk.startTimeUs);
    }
    downstreamTrackFormat = trackFormat;
    return sampleQueues.valueAt(group).readData(formatHolder, buffer, requireFormat, loadingFinished, lastSeekPositionUs);
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 54 with Format

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

the class ChunkSampleStream method discardDownstreamMediaChunks.

private void discardDownstreamMediaChunks(int primaryStreamReadIndex) {
    while (mediaChunks.size() > 1 && mediaChunks.get(1).getFirstSampleIndex(0) <= primaryStreamReadIndex) {
        mediaChunks.removeFirst();
    }
    BaseMediaChunk currentChunk = mediaChunks.getFirst();
    Format trackFormat = currentChunk.trackFormat;
    if (!trackFormat.equals(primaryDownstreamTrackFormat)) {
        eventDispatcher.downstreamFormatChanged(primaryTrackType, trackFormat, currentChunk.trackSelectionReason, currentChunk.trackSelectionData, currentChunk.startTimeUs);
    }
    primaryDownstreamTrackFormat = trackFormat;
}
Also used : Format(com.google.android.exoplayer2.Format)

Example 55 with Format

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

the class AdtsReader method parseAdtsHeader.

/**
   * 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);
        Format format = Format.createAudioSampleFormat(formatId, MimeTypes.AUDIO_AAC, null, Format.NO_VALUE, Format.NO_VALUE, audioParams.second, audioParams.first, Collections.singletonList(audioSpecificConfig), null, 0, language);
        // 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) / format.sampleRate;
        output.format(format);
        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);
}
Also used : Format(com.google.android.exoplayer2.Format)

Aggregations

Format (com.google.android.exoplayer2.Format)38 Point (android.graphics.Point)8 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)6 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)5 ArrayList (java.util.ArrayList)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 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 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)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