Main.java Source code

Java tutorial

Introduction

Here is the source code for Main.java

Source

//package com.java2s;
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.annotation.SuppressLint;
import android.media.MediaCodecInfo.CodecProfileLevel;
import android.util.Pair;

public class Main {
    private static final byte[] NAL_START_CODE = new byte[] { 0, 0, 0, 1 };
    private static final int SPS_NAL_UNIT_TYPE = 7;

    /**
     * Parses an SPS NAL unit.
     *
     * @param spsNalUnit The NAL unit.
     * @return A pair consisting of AVC profile and level constants, as defined in
     *     {@link android.media.MediaCodecInfo.CodecProfileLevel}. Null if the input data was not an SPS NAL unit.
     */
    public static Pair<Integer, Integer> parseSpsNalUnit(byte[] spsNalUnit) {
        // SPS NAL unit:
        // - Start prefix (4 bytes)
        // - Forbidden zero bit (1 bit)
        // - NAL ref idx (2 bits)
        // - NAL unit type (5 bits)
        // - Profile idc (8 bits)
        // - Constraint bits (3 bits)
        // - Reserved bits (5 bits)
        // - Level idx (8 bits)
        if (isNalStartCode(spsNalUnit, 0) && spsNalUnit.length == 8
                && (spsNalUnit[5] & 0x1F) == SPS_NAL_UNIT_TYPE) {
            return Pair.create(parseAvcProfile(spsNalUnit), parseAvcLevel(spsNalUnit));
        }
        return null;
    }

    /**
     * Tests whether there exists a NAL start code at a given index.
     *
     * @param data The data.
     * @param index The index to test.
     * @return Whether there exists a start code that begins at {@code index}.
     */
    private static boolean isNalStartCode(byte[] data, int index) {
        if (data.length - index <= NAL_START_CODE.length) {
            return false;
        }
        for (int j = 0; j < NAL_START_CODE.length; j++) {
            if (data[index + j] != NAL_START_CODE[j]) {
                return false;
            }
        }
        return true;
    }

    @SuppressLint("InlinedApi")
    private static int parseAvcProfile(byte[] data) {
        int profileIdc = data[6] & 0xFF;
        switch (profileIdc) {
        case 0x42:
            return CodecProfileLevel.AVCProfileBaseline;
        case 0x4d:
            return CodecProfileLevel.AVCProfileMain;
        case 0x58:
            return CodecProfileLevel.AVCProfileExtended;
        case 0x64:
            return CodecProfileLevel.AVCProfileHigh;
        case 0x6e:
            return CodecProfileLevel.AVCProfileHigh10;
        case 0x7a:
            return CodecProfileLevel.AVCProfileHigh422;
        case 0xf4:
            return CodecProfileLevel.AVCProfileHigh444;
        default:
            return 0;
        }
    }

    @SuppressLint("InlinedApi")
    private static int parseAvcLevel(byte[] data) {
        int levelIdc = data[8] & 0xFF;
        switch (levelIdc) {
        case 9:
            return CodecProfileLevel.AVCLevel1b;
        case 10:
            return CodecProfileLevel.AVCLevel1;
        case 11:
            return CodecProfileLevel.AVCLevel11;
        case 12:
            return CodecProfileLevel.AVCLevel12;
        case 13:
            return CodecProfileLevel.AVCLevel13;
        case 20:
            return CodecProfileLevel.AVCLevel2;
        case 21:
            return CodecProfileLevel.AVCLevel21;
        case 22:
            return CodecProfileLevel.AVCLevel22;
        case 30:
            return CodecProfileLevel.AVCLevel3;
        case 31:
            return CodecProfileLevel.AVCLevel31;
        case 32:
            return CodecProfileLevel.AVCLevel32;
        case 40:
            return CodecProfileLevel.AVCLevel4;
        case 41:
            return CodecProfileLevel.AVCLevel41;
        case 42:
            return CodecProfileLevel.AVCLevel42;
        case 50:
            return CodecProfileLevel.AVCLevel5;
        case 51:
            return CodecProfileLevel.AVCLevel51;
        default:
            return 0;
        }
    }
}