Search in sources :

Example 86 with Format

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

the class DtsUtil method parseDtsFormat.

/**
 * Returns the DTS format given {@code data} containing the DTS frame according to ETSI TS 102 114
 * subsections 5.3/5.4.
 *
 * @param frame The DTS frame to parse.
 * @param trackId The track identifier to set on the format.
 * @param language The language to set on the format.
 * @param drmInitData {@link DrmInitData} to be included in the format.
 * @return The DTS format parsed from data in the header.
 */
public static Format parseDtsFormat(byte[] frame, @Nullable String trackId, @Nullable String language, @Nullable DrmInitData drmInitData) {
    ParsableBitArray frameBits = getNormalizedFrameHeader(frame);
    // SYNC, FTYPE, SHORT, CPF, NBLKS, FSIZE
    frameBits.skipBits(32 + 1 + 5 + 1 + 7 + 14);
    int amode = frameBits.readBits(6);
    int channelCount = CHANNELS_BY_AMODE[amode];
    int sfreq = frameBits.readBits(4);
    int sampleRate = SAMPLE_RATE_BY_SFREQ[sfreq];
    int rate = frameBits.readBits(5);
    int bitrate = rate >= TWICE_BITRATE_KBPS_BY_RATE.length ? Format.NO_VALUE : TWICE_BITRATE_KBPS_BY_RATE[rate] * 1000 / 2;
    // MIX, DYNF, TIMEF, AUXF, HDCD, EXT_AUDIO_ID, EXT_AUDIO, ASPF
    frameBits.skipBits(10);
    // LFF
    channelCount += frameBits.readBits(2) > 0 ? 1 : 0;
    return new Format.Builder().setId(trackId).setSampleMimeType(MimeTypes.AUDIO_DTS).setAverageBitrate(bitrate).setChannelCount(channelCount).setSampleRate(sampleRate).setDrmInitData(drmInitData).setLanguage(language).build();
}
Also used : ParsableBitArray(com.google.android.exoplayer2.util.ParsableBitArray)

Example 87 with Format

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

the class DefaultTsPayloadReaderFactory method getClosedCaptionFormats.

/**
 * If {@link #FLAG_OVERRIDE_CAPTION_DESCRIPTORS} is set, returns a {@link List<Format>} of {@link
 * #closedCaptionFormats}. If unset, parses the PMT descriptor information and returns a {@link
 * List<Format>} 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 List<Format>} containing list of closed caption formats.
 */
private List<Format> getClosedCaptionFormats(EsInfo esInfo) {
    if (isSet(FLAG_OVERRIDE_CAPTION_DESCRIPTORS)) {
        return 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;
                }
                // easy_reader(1), wide_aspect_ratio(1), reserved(6).
                byte flags = (byte) scratchDescriptorData.readUnsignedByte();
                // Skip reserved (8).
                scratchDescriptorData.skipBytes(1);
                @Nullable List<byte[]> initializationData = null;
                // The wide_aspect_ratio flag only has meaning for CEA-708.
                if (isDigital) {
                    boolean isWideAspectRatio = (flags & 0x40) != 0;
                    initializationData = CodecSpecificDataUtil.buildCea708InitializationData(isWideAspectRatio);
                }
                closedCaptionFormats.add(new Format.Builder().setSampleMimeType(mimeType).setLanguage(language).setAccessibilityChannel(accessibilityChannel).setInitializationData(initializationData).build());
            }
        } else {
        // Unknown descriptor. Ignore.
        }
        scratchDescriptorData.setPosition(nextDescriptorPosition);
    }
    return closedCaptionFormats;
}
Also used : ParsableByteArray(com.google.android.exoplayer2.util.ParsableByteArray) Format(com.google.android.exoplayer2.Format) Nullable(androidx.annotation.Nullable)

Example 88 with Format

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

the class MpegAudioReader method readHeaderRemainder.

/**
 * Attempts to read the remaining two bytes of the frame header.
 *
 * <p>If a frame header is read in full then the state is changed to {@link #STATE_READING_FRAME},
 * the media format is output if this has not previously occurred, the four header bytes are
 * output as sample data, and the position of the source is advanced to the byte that immediately
 * follows the header.
 *
 * <p>If a frame header is read in full but cannot be parsed then the state is changed to {@link
 * #STATE_READING_HEADER}.
 *
 * <p>If a frame header is not read in full then the position of the source is advanced to the
 * limit, and the method should be called again with the next source to continue the read.
 *
 * @param source The source from which to read.
 */
@RequiresNonNull("output")
private void readHeaderRemainder(ParsableByteArray source) {
    int bytesToRead = min(source.bytesLeft(), HEADER_SIZE - frameBytesRead);
    source.readBytes(headerScratch.getData(), frameBytesRead, bytesToRead);
    frameBytesRead += bytesToRead;
    if (frameBytesRead < HEADER_SIZE) {
        // We haven't read the whole header yet.
        return;
    }
    headerScratch.setPosition(0);
    boolean parsedHeader = header.setForHeaderData(headerScratch.readInt());
    if (!parsedHeader) {
        // We thought we'd located a frame header, but we hadn't.
        frameBytesRead = 0;
        state = STATE_READING_HEADER;
        return;
    }
    frameSize = header.frameSize;
    if (!hasOutputFormat) {
        frameDurationUs = (C.MICROS_PER_SECOND * header.samplesPerFrame) / header.sampleRate;
        Format format = new Format.Builder().setId(formatId).setSampleMimeType(header.mimeType).setMaxInputSize(MpegAudioUtil.MAX_FRAME_SIZE_BYTES).setChannelCount(header.channels).setSampleRate(header.sampleRate).setLanguage(language).build();
        output.format(format);
        hasOutputFormat = true;
    }
    headerScratch.setPosition(0);
    output.sampleData(headerScratch, HEADER_SIZE);
    state = STATE_READING_FRAME;
}
Also used : Format(com.google.android.exoplayer2.Format) RequiresNonNull(org.checkerframework.checker.nullness.qual.RequiresNonNull)

Example 89 with Format

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

the class VorbisReader method readHeaders.

@Override
@EnsuresNonNullIf(expression = "#3.format", result = false)
protected boolean readHeaders(ParsableByteArray packet, long position, SetupData setupData) throws IOException {
    if (vorbisSetup != null) {
        checkNotNull(setupData.format);
        return false;
    }
    vorbisSetup = readSetupHeaders(packet);
    if (vorbisSetup == null) {
        return true;
    }
    VorbisSetup vorbisSetup = this.vorbisSetup;
    VorbisUtil.VorbisIdHeader idHeader = vorbisSetup.idHeader;
    ArrayList<byte[]> codecInitializationData = new ArrayList<>();
    codecInitializationData.add(idHeader.data);
    codecInitializationData.add(vorbisSetup.setupHeaderData);
    @Nullable Metadata metadata = VorbisUtil.parseVorbisComments(ImmutableList.copyOf(vorbisSetup.commentHeader.comments));
    setupData.format = new Format.Builder().setSampleMimeType(MimeTypes.AUDIO_VORBIS).setAverageBitrate(idHeader.bitrateNominal).setPeakBitrate(idHeader.bitrateMaximum).setChannelCount(idHeader.channels).setSampleRate(idHeader.sampleRate).setInitializationData(codecInitializationData).setMetadata(metadata).build();
    return true;
}
Also used : Format(com.google.android.exoplayer2.Format) ArrayList(java.util.ArrayList) Metadata(com.google.android.exoplayer2.metadata.Metadata) Nullable(androidx.annotation.Nullable) VorbisUtil(com.google.android.exoplayer2.extractor.VorbisUtil) EnsuresNonNullIf(org.checkerframework.checker.nullness.qual.EnsuresNonNullIf)

Example 90 with Format

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

the class Ac3Reader method parseHeader.

/**
 * Parses the sample header.
 */
@RequiresNonNull("output")
private void parseHeader() {
    headerScratchBits.setPosition(0);
    SyncFrameInfo frameInfo = Ac3Util.parseAc3SyncframeInfo(headerScratchBits);
    if (format == null || frameInfo.channelCount != format.channelCount || frameInfo.sampleRate != format.sampleRate || !Util.areEqual(frameInfo.mimeType, format.sampleMimeType)) {
        format = new Format.Builder().setId(formatId).setSampleMimeType(frameInfo.mimeType).setChannelCount(frameInfo.channelCount).setSampleRate(frameInfo.sampleRate).setLanguage(language).build();
        output.format(format);
    }
    sampleSize = frameInfo.frameSize;
    // In this class a sample is an access unit (syncframe in AC-3), but Format#sampleRate
    // specifies the number of PCM audio samples per second.
    sampleDurationUs = C.MICROS_PER_SECOND * frameInfo.sampleCount / format.sampleRate;
}
Also used : Format(com.google.android.exoplayer2.Format) SyncFrameInfo(com.google.android.exoplayer2.audio.Ac3Util.SyncFrameInfo) RequiresNonNull(org.checkerframework.checker.nullness.qual.RequiresNonNull)

Aggregations

Format (com.google.android.exoplayer2.Format)245 Test (org.junit.Test)178 Nullable (androidx.annotation.Nullable)65 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)62 TrackGroup (com.google.android.exoplayer2.source.TrackGroup)55 RendererCapabilities (com.google.android.exoplayer2.RendererCapabilities)35 ArrayList (java.util.ArrayList)32 DrmSessionEventListener (com.google.android.exoplayer2.drm.DrmSessionEventListener)26 FakeSampleStream (com.google.android.exoplayer2.testutil.FakeSampleStream)26 MediaFormat (android.media.MediaFormat)22 DefaultAllocator (com.google.android.exoplayer2.upstream.DefaultAllocator)22 SuppressLint (android.annotation.SuppressLint)18 Metadata (com.google.android.exoplayer2.metadata.Metadata)18 FakeTimeline (com.google.android.exoplayer2.testutil.FakeTimeline)18 FakeMediaSource (com.google.android.exoplayer2.testutil.FakeMediaSource)16 ImmutableList (com.google.common.collect.ImmutableList)16 AndroidJUnit4 (androidx.test.ext.junit.runners.AndroidJUnit4)15 EventStream (com.google.android.exoplayer2.source.dash.manifest.EventStream)15 SurfaceTexture (android.graphics.SurfaceTexture)14 Surface (android.view.Surface)14