Example usage for android.media MediaFormat MediaFormat

List of usage examples for android.media MediaFormat MediaFormat

Introduction

In this page you can find the example usage for android.media MediaFormat MediaFormat.

Prototype

public MediaFormat() 

Source Link

Document

Creates an empty MediaFormat

Usage

From source file:com.sonymobile.android.media.internal.ISOBMFFParser.java

protected boolean parseBox(BoxHeader header) {
    if (header == null) {
        return false;
    }// w  ww  .ja va 2s.c o  m
    mCurrentBoxSequence.add(header);

    if (LOGS_ENABLED)
        Log.v(TAG, "parse box " + ccruof(header.boxType) + " with size " + header.boxDataSize);

    boolean parseOK = true;
    long boxEndOffset = mCurrentOffset + header.boxDataSize;
    if (header.boxType == BOX_ID_FTYP) {

    } else if (header.boxType == BOX_ID_MOOV) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        // Merge tracks from moov and mfra
        if (mMfraTracks != null) {
            int numTracks = mTracks.size();
            int numMfraTracks = mMfraTracks.size();
            if (numMfraTracks > 0) {
                for (int i = 0; i < numTracks; i++) {
                    IsoTrack track = (IsoTrack) mTracks.get(i);
                    for (int j = 0; j < numMfraTracks; j++) {
                        IsoTrack t = mMfraTracks.get(j);
                        if (t.getTrackId() == track.getTrackId()) {
                            track.setTfraList(t.getTfraList());
                            mMfraTracks.remove(j);
                            break;
                        }
                    }
                }
            }
            mMfraTracks = null;
        }

        // Check for unsupported tracks
        int numTracks = mTracks.size();

        if (LOGS_ENABLED)
            Log.v(TAG,
                    numTracks + " tracks, " + "Video track " + getSelectedTrackIndex(TrackType.VIDEO)
                            + " Audio track " + getSelectedTrackIndex(TrackType.AUDIO) + " Subtitle track "
                            + getSelectedTrackIndex(TrackType.SUBTITLE));

        for (int i = 0; i < numTracks; i++) {
            IsoTrack track = (IsoTrack) mTracks.get(i);
            if (track.getMediaFormat() == null) {
                if (LOGS_ENABLED)
                    Log.v(TAG, "Track " + i + " is unhandled, type " + track.getTrackType());
                track.setTrackType(TrackType.UNKNOWN);
            } else {
                if (LOGS_ENABLED)
                    Log.v(TAG, "Track " + i + " of type " + track.getTrackType() + " is OK");
                track.setTrackIndex(i);
            }
        }

    } else if (header.boxType == BOX_ID_MVHD) {
        parseOK = parseMvhd(header);
    } else if (header.boxType == BOX_ID_TRAK) {
        mIsParsingTrack = true;
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        if (mParseODSMData) {
            if (!parseODSMData(mCurrentTrack)) {
                if (LOGS_ENABLED)
                    Log.e(TAG, "Error while parsing ODSM track");
                mCurrentBoxSequence.removeLast();
                return false;
            }
            mParseODSMData = false;
        }
        mIsParsingTrack = false;
    } else if (header.boxType == BOX_ID_TKHD) {
        parseOK = readTkhd(header);
    } else if (header.boxType == BOX_ID_MDIA) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_MDHD) {
        parseOK = parseMdhd(header);
    } else if (header.boxType == BOX_ID_HDLR) {
        parseOK = parseHdlr(header);
    } else if (header.boxType == BOX_ID_MINF) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }

        if (parseOK) {
            if (mCurrentTrack.getTrackType() == TrackType.AUDIO && mCurrentAudioTrack == null) {
                if (LOGS_ENABLED)
                    Log.v(TAG, "Setting audio track to " + mCurrentTrack.getTrackId());
                mCurrentAudioTrack = mCurrentTrack;
            } else if (mCurrentTrack.getTrackType() == TrackType.VIDEO && mCurrentVideoTrack == null) {
                if (LOGS_ENABLED)
                    Log.v(TAG, "Setting video track to " + mCurrentTrack.getTrackId());
                mCurrentVideoTrack = mCurrentTrack;
            }
        } else {
            if (LOGS_ENABLED)
                Log.e(TAG, "Error parsing minf boxes");
        }
    } else if (header.boxType == BOX_ID_STBL) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        if (parseOK) {
            IsoTrack currentTrack = (IsoTrack) mTracks.get(mTracks.size() - 1);
            SampleTable sampleTable = currentTrack.getSampleTable();
            sampleTable.setTimescale(currentTrack.getTimeScale());

            if (sampleTable.calculateSampleCountAndDuration() == false) {
                if (LOGS_ENABLED)
                    Log.w(TAG, "Error while calculating sample count and duration");
            }
            int sampleCount = sampleTable.getSampleCount();
            if (sampleCount > 0) {
                mHasSampleTable = true;
            }
            long trackDurationUs = currentTrack.getDurationUs();
            if (trackDurationUs > 0) {
                float frameRate = (sampleCount * 1000000.0f / trackDurationUs);
                mCurrentTrack.getMetaData().addValue(KEY_FRAME_RATE, frameRate);
            } else {
                mCurrentTrack.getMetaData().addValue(KEY_FRAME_RATE, 0f);
            }
        }
    } else if (header.boxType == BOX_ID_STSD) {
        // skip 4 for version and flags
        // skip 4 for entry_count
        mCurrentOffset += 8;
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }

        if (mCurrentTrack.getMediaFormat() == null) {
            if (LOGS_ENABLED)
                Log.w(TAG, "Error parsing handler in 'stsd' box");
            mCurrentTrack.setTrackType(TrackType.UNKNOWN);
        }
    } else if (header.boxType == BOX_ID_AVC1 || header.boxType == BOX_ID_AVC3) {
        byte[] data = new byte[78];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Error while parsing 'avc1' box", e);
            mCurrentBoxSequence.removeLast();
            return false;
        }

        mCurrentMediaFormat = new MediaFormat();

        parseVisualSampleEntry(data);

        mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.AVC);
        // TODO: Update this when we add support for nalSize other than 4
        mCurrentMediaFormat.setInteger("nal-size", 4);
        mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.AVC);

        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        mCurrentTrack.addSampleDescriptionEntry(mCurrentMediaFormat);

    } else if (header.boxType == BOX_ID_AVCC) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Error while parsing 'avcc' box", e);
            mCurrentBoxSequence.removeLast();
            return false;
        }

        AvccData avccData = parseAvcc(data);
        if (avccData == null) {
            return false;
        }
        ByteBuffer csd0 = ByteBuffer.wrap(avccData.spsBuffer.array());
        ByteBuffer csd1 = ByteBuffer.wrap(avccData.ppsBuffer.array());
        mCurrentMediaFormat.setByteBuffer("csd-0", csd0);
        mCurrentMediaFormat.setByteBuffer("csd-1", csd1);
        mCurrentMediaFormat.setInteger("nal-length-size", mNALLengthSize);

        parseSPS(avccData.spsBuffer.array());
    } else if (header.boxType == BOX_ID_STTS) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'stts' box", e);
        }
        mCurrentTrack.getSampleTable().setSttsData(data);
    } else if (header.boxType == BOX_ID_STSZ) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'stsz' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
        mCurrentTrack.getSampleTable().setStszData(data);
    } else if (header.boxType == BOX_ID_CTTS) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'ctts' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
        mCurrentTrack.getSampleTable().setCttsData(data);
    } else if (header.boxType == BOX_ID_STSC) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'stsc' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
        mCurrentTrack.getSampleTable().setStscData(data);
    } else if (header.boxType == BOX_ID_STSS) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'stss' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
        mCurrentTrack.getSampleTable().setStssData(data);
    } else if (header.boxType == BOX_ID_STCO) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'stco' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
        mCurrentTrack.getSampleTable().setStcoData(data);
    } else if (header.boxType == BOX_ID_CO64) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'co64' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
        mCurrentTrack.getSampleTable().setCo64Data(data);
    } else if (header.boxType == BOX_ID_MP4V) {
        byte[] data = new byte[78];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'mp4v' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }

        mCurrentMediaFormat = new MediaFormat();

        // mp4v is a type of VisualSampleEntry
        parseVisualSampleEntry(data);

        mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.MPEG4_VISUAL);
        mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.MPEG4_VISUAL);

        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        mCurrentTrack.addSampleDescriptionEntry(mCurrentMediaFormat);
    } else if (header.boxType == BOX_ID_MP4A) {
        byte[] data = new byte[28];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'mp4a' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }

        mCurrentMediaFormat = new MediaFormat();

        parseAudioSampleEntry(data);

        mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.AAC);
        mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.AAC);

        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        mCurrentTrack.addSampleDescriptionEntry(mCurrentMediaFormat);
    } else if (header.boxType == BOX_ID_ESDS) {
        // skip 4 for version and flags
        mCurrentOffset += 4;
        byte[] data = new byte[(int) header.boxDataSize - 4];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'esds' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
        parseOK = parseESDS(data);
    } else if (header.boxType == BOX_ID_STPP) {
        mCurrentOffset += header.boxDataSize;

        mCurrentMediaFormat = new MediaFormat();

        mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.TTML);
        mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.TTML);

        mCurrentTrack.addSampleDescriptionEntry(mCurrentMediaFormat);
    } else if (header.boxType == BOX_ID_MVEX) {
        if (LOGS_ENABLED)
            Log.v(TAG, "found 'mvex', setting fragmented to true");
        mIsFragmented = true;
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_MEHD) {
        int versionFlags = 0;
        try {
            versionFlags = mDataSource.readInt();
            int version = (versionFlags >> 24) & 0xFF;

            long durationTicks = 0;
            if (version == 1) {
                durationTicks = mDataSource.readLong();
            } else {
                durationTicks = mDataSource.readInt();
            }
            addMetaDataValue(KEY_DURATION, durationTicks * 1000 / mFileTimescale);
        } catch (EOFException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "EOFException while parsing 'mvex' box", e);
            mCurrentBoxSequence.removeLast();

            return false;
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'mehd' box", e);
            mCurrentBoxSequence.removeLast();

            return false;
        }
    } else if (header.boxType == BOX_ID_TREX) {
        try {
            Trex newTrex = new Trex();
            mDataSource.skipBytes(4); // version and flags
            int trackId = mDataSource.readInt();
            mDataSource.skipBytes(4); // Skip Default Sample Description Index
            newTrex.defaultSampleDuration = mDataSource.readInt();
            newTrex.defaultSampleSize = mDataSource.readInt();
            mDataSource.skipBytes(4); // Skip Default Sample Flags

            IsoTrack track = null;
            int numTracks = mTracks.size();
            for (int i = 0; i < numTracks; i++) {
                IsoTrack t = (IsoTrack) (mTracks.get(i));
                if (t.getTrackId() == trackId) {
                    track = t;
                    break;
                }
            }

            if (track == null) {
                track = (IsoTrack) createTrack();
                track.setTrackId(trackId);
                mTracks.add(track);
            }

            if (track != null) {
                track.setTrex(newTrex);
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'trex' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }
    } else if (header.boxType == BOX_ID_MOOF) {
        if (mFirstMoofOffset == -1) {
            mIsFragmented = true;
            mInitDone = true;
            mFirstMoofOffset = header.startOffset;
            mCurrentBoxSequence.removeLast();
            return true;
        }
        mCurrentMoofOffset = header.startOffset;
        mMoofDataSize = 0;
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_TRAF) {
        mParsedSencData = false;
        mCurrentTrackFragment = new Traf();
        mPrevTrunDataSize = 0;
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_TFHD) {
        parseOK = parseTfhd(header);
    } else if (header.boxType == BOX_ID_TRUN) {
        parseOK = parseTrun(header);
    } else if (header.boxType == BOX_ID_MFRA) {
        if (!mFoundMfra) {
            mMfraTracks = new ArrayList<ISOBMFFParser.IsoTrack>(2);
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mFoundMfra = true;
        }
    } else if (header.boxType == BOX_ID_TFRA) {
        parseOK = parseTfra(header);
    } else if (header.boxType == BOX_ID_ENCA) {
        byte[] data = new byte[28];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'enca' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }

        mCurrentMediaFormat = new MediaFormat();

        parseAudioSampleEntry(data);

        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        mCurrentTrack.addSampleDescriptionEntry(mCurrentMediaFormat);
    } else if (header.boxType == BOX_ID_ENCV) {
        byte[] data = new byte[78];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'encv' box", e);

            mCurrentBoxSequence.removeLast();
            return false;
        }

        mCurrentMediaFormat = new MediaFormat();

        parseVisualSampleEntry(data);

        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        mCurrentTrack.addSampleDescriptionEntry(mCurrentMediaFormat);
    } else if (header.boxType == BOX_ID_FRMA) {
        try {
            int dataFormat = mDataSource.readInt();
            if (dataFormat == BOX_ID_AVC1) {
                mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.AVC);
                mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.AVC);
            } else if (dataFormat == BOX_ID_HVC1) {
                mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.HEVC);
                mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.HEVC);
            } else if (dataFormat == BOX_ID_MP4V) {
                mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.MPEG4_VISUAL);
                mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.MPEG4_VISUAL);
            } else if (dataFormat == BOX_ID_MP4A) {
                mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.AAC);
                mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.AAC);
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Exception while parsing 'frma' box", e);
            mCurrentBoxSequence.removeLast();
            return false;
        }
    } else if (header.boxType == BOX_ID_SCHM) {
        try {
            int versionFlags = mDataSource.readInt();
            mDataSource.skipBytes(8); // scheme_type and scheme_version
            if ((versionFlags & 0x01) != 0) {
                // TODO read scheme_uri if we're interested
                // byte[] data = new byte[(int)header.boxDataSize - 12];
                // mDataSource.read(data);
                mDataSource.skipBytes(header.boxDataSize - 12);
            }
        } catch (EOFException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Error parsing 'schm' box", e);

            mCurrentBoxSequence.removeLast();
            parseOK = false;
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Error parsing 'schm' box", e);

            mCurrentBoxSequence.removeLast();
            parseOK = false;
        }
    } else if (header.boxType == BOX_ID_SCHI) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_EDTS) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_ELST) {
        parseOK = parseElst(header);
    } else if (header.boxType == BOX_ID_PSSH) {
        parseOK = parsePsshData(header);
    } else if (header.boxType == BOX_ID_TENC) {
        try {
            // Skip version, flags and algorithm id
            mDataSource.skipBytes(7);
            int ivSize = mDataSource.readByte();
            byte[] kID = new byte[16];
            mDataSource.read(kID);
            mCurrentTrack.setDefaultEncryptionData(ivSize, kID);
            parseOK = true;
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'tenc' box", e);
            parseOK = false;
        }
    } else if (header.boxType == BOX_ID_SENC) {
        if (mCurrentMoofTrackId == mCurrentTrackId && !mSkipInsertSamples && !mParsedSencData) {
            mParsedSencData = true;
            try {
                int versionFlags = mDataSource.readInt();

                int sampleCount = mDataSource.readInt();

                ArrayList<CryptoInfo> cryptoInfos = new ArrayList<CryptoInfo>(sampleCount);

                for (int i = 0; i < sampleCount; i++) {
                    CryptoInfo info = new CryptoInfo();
                    info.mode = MediaCodec.CRYPTO_MODE_AES_CTR;
                    info.iv = new byte[16];
                    if (mCurrentTrack.mDefaultIVSize == 16) {
                        mDataSource.read(info.iv);
                    } else {
                        // pad IV data to 128 bits
                        byte[] iv = new byte[8];
                        mDataSource.read(iv);
                        System.arraycopy(iv, 0, info.iv, 0, 8);
                    }
                    if ((versionFlags & 0x00000002) > 0) {
                        short subSampleCount = mDataSource.readShort();
                        info.numSubSamples = subSampleCount;
                        info.numBytesOfClearData = new int[subSampleCount];
                        info.numBytesOfEncryptedData = new int[subSampleCount];
                        for (int j = 0; j < subSampleCount; j++) {
                            info.numBytesOfClearData[j] = mDataSource.readShort();
                            info.numBytesOfEncryptedData[j] = mDataSource.readInt();
                        }
                    } else {
                        info.numSubSamples = 1;
                        info.numBytesOfClearData = new int[1];
                        info.numBytesOfClearData[0] = 0;
                        info.numBytesOfEncryptedData = new int[1];
                        info.numBytesOfEncryptedData[0] = -1;
                    }

                    if (info.numBytesOfClearData[0] == 0 && mCurrentTrack.getTrackType() == TrackType.VIDEO) {
                        info.iv[15] = (byte) mNALLengthSize;
                    }

                    cryptoInfos.add(info);
                }

                mCurrentTrack.addCryptoInfos(cryptoInfos);
            } catch (EOFException e) {
                if (LOGS_ENABLED)
                    Log.e(TAG, "Error parsing 'senc' box", e);

                mCurrentBoxSequence.removeLast();
                parseOK = false;
            } catch (IOException e) {
                if (LOGS_ENABLED)
                    Log.e(TAG, "Error parsing 'senc' box", e);

                mCurrentBoxSequence.removeLast();
                parseOK = false;
            }
        }
    } else if (header.boxType == BOX_ID_SINF) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_HVC1 || header.boxType == BOX_ID_HEV1) {
        byte[] data = new byte[78];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'hvc1' box", e);
            return false;
        }

        mCurrentMediaFormat = new MediaFormat();

        mCurrentMediaFormat.setString(MediaFormat.KEY_MIME, MimeType.HEVC);
        mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, MimeType.HEVC);

        parseVisualSampleEntry(data);

        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        mCurrentTrack.addSampleDescriptionEntry(mCurrentMediaFormat);
    } else if (header.boxType == BOX_ID_HVCC) {
        byte[] data = new byte[(int) header.boxDataSize];
        try {
            if (mDataSource.readAt(mCurrentOffset, data, data.length) != data.length) {
                mCurrentBoxSequence.removeLast();
                return false;
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException while parsing 'hvcc' box", e);
            return false;
        }

        byte[] hvccData = parseHvcc(data);
        if (hvccData == null) {
            return false;
        }
        ByteBuffer csd0 = ByteBuffer.wrap(hvccData);
        mCurrentMediaFormat.setByteBuffer("csd-0", csd0);
        mCurrentMediaFormat.setInteger("nal-length-size", mNALLengthSize);
    } else if (header.boxType == BOX_ID_UDTA) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_META) {
        mCurrentOffset += 4; // skip version and flags
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_ILST) {
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
    } else if (header.boxType == BOX_ID_ATNAM) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_TITLE;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_ATALB) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_ALBUM;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_ATART) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_ARTIST;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_AART) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_ALBUM_ARTIST;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_ATDAY) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_YEAR;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_TRKN) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_TRACK_NUMBER;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_ATGEN || header.boxType == BOX_ID_GNRE) {
        mCurrentMetaDataKey = KEY_GENRE;
        if (boxIsUnder(BOX_ID_ILST)) {
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
        } else { // 3gpp metadata value
            try {
                mDataSource.skipBytes(4); // skip version and flags
                mDataSource.skipBytes(2); // skip language code
                byte[] buffer = new byte[(int) (header.boxDataSize - 6)];
                mDataSource.read(buffer);
                String metaDataValue = null;
                if ((0xFF & buffer[0]) == 0xFF && (0xFF & buffer[1]) == 0xFE
                        || (0xFF & buffer[0]) == 0xFE && (0xFF & buffer[1]) == 0xFF) {
                    metaDataValue = new String(buffer, 0, buffer.length - 2, StandardCharsets.UTF_16);
                } else {
                    metaDataValue = new String(buffer, 0, buffer.length - 1, StandardCharsets.UTF_8);
                }
                addMetaDataValue(mCurrentMetaDataKey, metaDataValue);
            } catch (IOException e) {
                if (LOGS_ENABLED)
                    Log.e(TAG, "IOException parsing 'gnre' box", e);
                parseOK = false;
            }
        }
        mCurrentMetaDataKey = null;
    } else if (header.boxType == BOX_ID_CPIL) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_COMPILATION;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_ATWRT) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_WRITER;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_DISK) {
        if (boxIsUnder(BOX_ID_ILST)) {
            mCurrentMetaDataKey = KEY_DISC_NUMBER;
            while (mCurrentOffset < boxEndOffset && parseOK) {
                BoxHeader nextBoxHeader = getNextBoxHeader();
                parseOK = parseBox(nextBoxHeader);
            }
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_DATA) {
        parseOK = parseDataBox(header);
    } else if (header.boxType == BOX_ID_ID32) {
        parseOK = parseID3(header);
    } else if (header.boxType == BOX_ID_TITL) {
        if (!mMetaDataValues.containsKey(KEY_TITLE)) {
            mCurrentMetaDataKey = KEY_TITLE;
            parseOK = parse3GPPMetaDataString(header);
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_PERF) {
        if (!mMetaDataValues.containsKey(KEY_ARTIST)) {
            mCurrentMetaDataKey = KEY_ARTIST;
            parseOK = parse3GPPMetaDataString(header);
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_AUTH) {
        if (!mMetaDataValues.containsKey(KEY_AUTHOR)) {
            mCurrentMetaDataKey = KEY_AUTHOR;
            parseOK = parse3GPPMetaDataString(header);
            mCurrentMetaDataKey = null;
        }
    } else if (header.boxType == BOX_ID_ALBM) {
        if (!mMetaDataValues.containsKey(KEY_ALBUM)) {
            try {
                mDataSource.skipBytes(4); // skip version and flags
                mDataSource.skipBytes(2); // skip language code
                byte[] buffer = new byte[(int) (header.boxDataSize - 6)];
                mDataSource.read(buffer);
                String metaDataValue = null;
                if ((0xFF & buffer[0]) == 0xFF && (0xFF & buffer[1]) == 0xFE) {
                    if (buffer[buffer.length - 3] == 0 && buffer[buffer.length - 2] == 0) {
                        if (!mMetaDataValues.containsKey(KEY_TRACK_NUMBER)) {
                            String trackNumber = Byte.toString(buffer[buffer.length - 1]);
                            addMetaDataValue(KEY_TRACK_NUMBER, trackNumber);
                        }
                        metaDataValue = new String(buffer, 0, buffer.length - 3, StandardCharsets.UTF_16);
                    } else {
                        metaDataValue = new String(buffer, StandardCharsets.UTF_16);
                    }
                } else if ((0xFF & buffer[0]) == 0xFE && (0xFF & buffer[1]) == 0xFF) {
                    if (buffer[buffer.length - 3] == 0 && buffer[buffer.length - 2] == 0) {
                        if (!mMetaDataValues.containsKey(KEY_TRACK_NUMBER)) {
                            String trackNumber = Byte.toString(buffer[buffer.length - 1]);
                            addMetaDataValue(KEY_TRACK_NUMBER, trackNumber);
                        }
                        metaDataValue = new String(buffer, 0, buffer.length - 3, StandardCharsets.UTF_16);
                    } else {
                        metaDataValue = new String(buffer, 0, buffer.length - 2, StandardCharsets.UTF_16);
                    }
                } else {
                    if (buffer[buffer.length - 2] == 0) {
                        if (!mMetaDataValues.containsKey(KEY_TRACK_NUMBER)) {
                            String trackNumber = Byte.toString(buffer[buffer.length - 1]);
                            addMetaDataValue(KEY_TRACK_NUMBER, trackNumber);
                        }
                        metaDataValue = new String(buffer, 0, buffer.length - 2, StandardCharsets.UTF_8);
                    } else {
                        metaDataValue = new String(buffer, 0, buffer.length - 1, StandardCharsets.UTF_8);
                    }
                }
                addMetaDataValue(KEY_ALBUM, metaDataValue);
            } catch (IOException e) {
                if (LOGS_ENABLED)
                    Log.e(TAG, "IOException parsing 'albm' box", e);
                parseOK = false;
            }
        }
    } else if (header.boxType == BOX_ID_YRRC) {
        try {
            mDataSource.skipBytes(4); // skip version and flags
            if (header.boxDataSize > 6) {
                // This should be a 16 bit int according to spec, but some
                // files have this as a string
                mDataSource.skipBytes(2); // skip language code
                byte[] buffer = new byte[(int) (header.boxDataSize - 6)];
                mDataSource.read(buffer);
                String metaDataValue = null;
                if ((0xFF & buffer[0]) == 0xFF && (0xFF & buffer[1]) == 0xFE
                        || (0xFF & buffer[0]) == 0xFE && (0xFF & buffer[1]) == 0xFF) {
                    metaDataValue = new String(buffer, 0, buffer.length - 2, StandardCharsets.UTF_16);
                } else {
                    metaDataValue = new String(buffer, 0, buffer.length - 1, StandardCharsets.UTF_8);
                }
                addMetaDataValue(KEY_YEAR, metaDataValue);
            } else {
                int year = mDataSource.readShort();
                String metaDataValue = Integer.toString(year);
                addMetaDataValue(KEY_YEAR, metaDataValue);
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "IOException parsing 'yrrc' box", e);
            parseOK = false;
        }
    } else if (header.boxType == BOX_ID_MDAT) {
        if (mTracks.size() > 0 && !mIsFragmented) {
            mInitDone = true;
        } else if (mIsFragmented && mFirstMoofOffset != -1) {
            mInitDone = true;
        } else {
            mMdatFound = true;
        }
    } else {
        long skipSize = header.boxDataSize;
        try {
            while (skipSize > Integer.MAX_VALUE) {
                mDataSource.skipBytes(Integer.MAX_VALUE);
                skipSize -= Integer.MAX_VALUE;
            }
            if (skipSize > 0) {
                mDataSource.skipBytes(skipSize);
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "could not skip box");

            mCurrentBoxSequence.removeLast();
            parseOK = false;
        }
    }
    mCurrentOffset = boxEndOffset;
    mCurrentBoxSequence.removeLast();
    return parseOK;
}

From source file:com.serenegiant.media.TLMediaEncoder.java

private static final MediaFormat asMediaFormat(final String format_str) {
    MediaFormat format = new MediaFormat();
    try {/* w  ww  .j  a  v  a2 s .c o m*/
        final JSONObject map = new JSONObject(format_str);
        if (map.has(MediaFormat.KEY_MIME))
            format.setString(MediaFormat.KEY_MIME, (String) map.get(MediaFormat.KEY_MIME));
        if (map.has(MediaFormat.KEY_WIDTH))
            format.setInteger(MediaFormat.KEY_WIDTH, (Integer) map.get(MediaFormat.KEY_WIDTH));
        if (map.has(MediaFormat.KEY_HEIGHT))
            format.setInteger(MediaFormat.KEY_HEIGHT, (Integer) map.get(MediaFormat.KEY_HEIGHT));
        if (map.has(MediaFormat.KEY_BIT_RATE))
            format.setInteger(MediaFormat.KEY_BIT_RATE, (Integer) map.get(MediaFormat.KEY_BIT_RATE));
        if (map.has(MediaFormat.KEY_COLOR_FORMAT))
            format.setInteger(MediaFormat.KEY_COLOR_FORMAT, (Integer) map.get(MediaFormat.KEY_COLOR_FORMAT));
        if (map.has(MediaFormat.KEY_FRAME_RATE))
            format.setInteger(MediaFormat.KEY_FRAME_RATE, (Integer) map.get(MediaFormat.KEY_FRAME_RATE));
        if (map.has(MediaFormat.KEY_I_FRAME_INTERVAL))
            format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
                    (Integer) map.get(MediaFormat.KEY_I_FRAME_INTERVAL));
        if (map.has(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER))
            format.setLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER,
                    (Long) map.get(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER));
        if (map.has(MediaFormat.KEY_MAX_INPUT_SIZE))
            format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE,
                    (Integer) map.get(MediaFormat.KEY_MAX_INPUT_SIZE));
        if (map.has(MediaFormat.KEY_DURATION))
            format.setInteger(MediaFormat.KEY_DURATION, (Integer) map.get(MediaFormat.KEY_DURATION));
        if (map.has(MediaFormat.KEY_CHANNEL_COUNT))
            format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, (Integer) map.get(MediaFormat.KEY_CHANNEL_COUNT));
        if (map.has(MediaFormat.KEY_SAMPLE_RATE))
            format.setInteger(MediaFormat.KEY_SAMPLE_RATE, (Integer) map.get(MediaFormat.KEY_SAMPLE_RATE));
        if (map.has(MediaFormat.KEY_CHANNEL_MASK))
            format.setInteger(MediaFormat.KEY_CHANNEL_MASK, (Integer) map.get(MediaFormat.KEY_CHANNEL_MASK));
        if (map.has(MediaFormat.KEY_AAC_PROFILE))
            format.setInteger(MediaFormat.KEY_AAC_PROFILE, (Integer) map.get(MediaFormat.KEY_AAC_PROFILE));
        if (map.has(MediaFormat.KEY_AAC_SBR_MODE))
            format.setInteger(MediaFormat.KEY_AAC_SBR_MODE, (Integer) map.get(MediaFormat.KEY_AAC_SBR_MODE));
        if (map.has(MediaFormat.KEY_MAX_INPUT_SIZE))
            format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE,
                    (Integer) map.get(MediaFormat.KEY_MAX_INPUT_SIZE));
        if (map.has(MediaFormat.KEY_IS_ADTS))
            format.setInteger(MediaFormat.KEY_IS_ADTS, (Integer) map.get(MediaFormat.KEY_IS_ADTS));
        if (map.has("what"))
            format.setInteger("what", (Integer) map.get("what"));
        if (map.has("csd-0"))
            format.setByteBuffer("csd-0", asByteBuffer((String) map.get("csd-0")));
        if (map.has("csd-1"))
            format.setByteBuffer("csd-1", asByteBuffer((String) map.get("csd-1")));
    } catch (JSONException e) {
        Log.e(TAG_STATIC, "writeFormat:" + format_str, e);
        format = null;
    }
    return format;
}