Search in sources :

Example 1 with SpsData

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

the class AvcConfig method parse.

/**
 * Parses AVC configuration data.
 *
 * @param data A {@link ParsableByteArray}, whose position is set to the start of the AVC
 *     configuration data to parse.
 * @return A parsed representation of the AVC configuration data.
 * @throws ParserException If an error occurred parsing the data.
 */
public static AvcConfig parse(ParsableByteArray data) throws ParserException {
    try {
        // Skip to the AVCDecoderConfigurationRecord (defined in 14496-15)
        data.skipBytes(4);
        int nalUnitLengthFieldLength = (data.readUnsignedByte() & 0x3) + 1;
        if (nalUnitLengthFieldLength == 3) {
            throw new IllegalStateException();
        }
        List<byte[]> initializationData = new ArrayList<>();
        int numSequenceParameterSets = data.readUnsignedByte() & 0x1F;
        for (int j = 0; j < numSequenceParameterSets; j++) {
            initializationData.add(buildNalUnitForChild(data));
        }
        int numPictureParameterSets = data.readUnsignedByte();
        for (int j = 0; j < numPictureParameterSets; j++) {
            initializationData.add(buildNalUnitForChild(data));
        }
        int width = Format.NO_VALUE;
        int height = Format.NO_VALUE;
        float pixelWidthHeightRatio = 1;
        @Nullable String codecs = null;
        if (numSequenceParameterSets > 0) {
            byte[] sps = initializationData.get(0);
            SpsData spsData = NalUnitUtil.parseSpsNalUnit(initializationData.get(0), nalUnitLengthFieldLength, sps.length);
            width = spsData.width;
            height = spsData.height;
            pixelWidthHeightRatio = spsData.pixelWidthHeightRatio;
            codecs = CodecSpecificDataUtil.buildAvcCodecString(spsData.profileIdc, spsData.constraintsFlagsAndReservedZero2Bits, spsData.levelIdc);
        }
        return new AvcConfig(initializationData, nalUnitLengthFieldLength, width, height, pixelWidthHeightRatio, codecs);
    } catch (ArrayIndexOutOfBoundsException e) {
        throw ParserException.createForMalformedContainer("Error parsing AVC config", e);
    }
}
Also used : ArrayList(java.util.ArrayList) SpsData(com.google.android.exoplayer2.util.NalUnitUtil.SpsData) Nullable(androidx.annotation.Nullable)

Example 2 with SpsData

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

the class H264Reader method endNalUnit.

@RequiresNonNull({ "output", "sampleReader" })
private void endNalUnit(long position, int offset, int discardPadding, long pesTimeUs) {
    if (!hasOutputFormat || sampleReader.needsSpsPps()) {
        sps.endNalUnit(discardPadding);
        pps.endNalUnit(discardPadding);
        if (!hasOutputFormat) {
            if (sps.isCompleted() && pps.isCompleted()) {
                List<byte[]> initializationData = new ArrayList<>();
                initializationData.add(Arrays.copyOf(sps.nalData, sps.nalLength));
                initializationData.add(Arrays.copyOf(pps.nalData, pps.nalLength));
                NalUnitUtil.SpsData spsData = NalUnitUtil.parseSpsNalUnit(sps.nalData, 3, sps.nalLength);
                NalUnitUtil.PpsData ppsData = NalUnitUtil.parsePpsNalUnit(pps.nalData, 3, pps.nalLength);
                String codecs = CodecSpecificDataUtil.buildAvcCodecString(spsData.profileIdc, spsData.constraintsFlagsAndReservedZero2Bits, spsData.levelIdc);
                output.format(new Format.Builder().setId(formatId).setSampleMimeType(MimeTypes.VIDEO_H264).setCodecs(codecs).setWidth(spsData.width).setHeight(spsData.height).setPixelWidthHeightRatio(spsData.pixelWidthHeightRatio).setInitializationData(initializationData).build());
                hasOutputFormat = true;
                sampleReader.putSps(spsData);
                sampleReader.putPps(ppsData);
                sps.reset();
                pps.reset();
            }
        } else if (sps.isCompleted()) {
            NalUnitUtil.SpsData spsData = NalUnitUtil.parseSpsNalUnit(sps.nalData, 3, sps.nalLength);
            sampleReader.putSps(spsData);
            sps.reset();
        } else if (pps.isCompleted()) {
            NalUnitUtil.PpsData ppsData = NalUnitUtil.parsePpsNalUnit(pps.nalData, 3, pps.nalLength);
            sampleReader.putPps(ppsData);
            pps.reset();
        }
    }
    if (sei.endNalUnit(discardPadding)) {
        int unescapedLength = NalUnitUtil.unescapeStream(sei.nalData, sei.nalLength);
        seiWrapper.reset(sei.nalData, unescapedLength);
        // NAL prefix and nal_unit() header.
        seiWrapper.setPosition(4);
        seiReader.consume(pesTimeUs, seiWrapper);
    }
    boolean sampleIsKeyFrame = sampleReader.endNalUnit(position, offset, hasOutputFormat, randomAccessIndicator);
    if (sampleIsKeyFrame) {
        // This is either an IDR frame or the first I-frame since the random access indicator, so mark
        // it as a keyframe. Clear the flag so that subsequent non-IDR I-frames are not marked as
        // keyframes until we see another random access indicator.
        randomAccessIndicator = false;
    }
}
Also used : SpsData(com.google.android.exoplayer2.util.NalUnitUtil.SpsData) Format(com.google.android.exoplayer2.Format) NalUnitUtil(com.google.android.exoplayer2.util.NalUnitUtil) ArrayList(java.util.ArrayList) SpsData(com.google.android.exoplayer2.util.NalUnitUtil.SpsData) RequiresNonNull(org.checkerframework.checker.nullness.qual.RequiresNonNull)

Aggregations

SpsData (com.google.android.exoplayer2.util.NalUnitUtil.SpsData)2 ArrayList (java.util.ArrayList)2 Nullable (androidx.annotation.Nullable)1 Format (com.google.android.exoplayer2.Format)1 NalUnitUtil (com.google.android.exoplayer2.util.NalUnitUtil)1 RequiresNonNull (org.checkerframework.checker.nullness.qual.RequiresNonNull)1