Example usage for android.media MediaFormat KEY_MIME

List of usage examples for android.media MediaFormat KEY_MIME

Introduction

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

Prototype

String KEY_MIME

To view the source code for android.media MediaFormat KEY_MIME.

Click Source Link

Document

A key describing the mime type of the MediaFormat.

Usage

From source file:com.musicplayer.AudioDecoderThread.java

/**
 * After decoding AAC, Play using Audio Track.
 * /*from w w w . jav  a2 s  .  com*/
 */

public void processTrack(Uri syncContentUri, final Genre classLabel, Context context,
        ProcessTrackRunnable lock) {

    // INITIALISE EXTRACTOR AND DECODER
    Log.v("", "Break Point 1");

    MediaExtractor extractor = new MediaExtractor();
    int sampleRate = 0;
    Uri contentUri = null;
    synchronized (lock) {
        contentUri = syncContentUri;
    }
    try {
        extractor.setDataSource(context, contentUri, null);
    } catch (IOException e) {
        e.printStackTrace();
    }
    int channel = 0;

    for (int i = 0; i < extractor.getTrackCount(); i++) {
        MediaFormat format = extractor.getTrackFormat(i);
        String mime = format.getString(MediaFormat.KEY_MIME);
        if (mime.startsWith("audio/")) {
            extractor.selectTrack(i);
            Log.d("", "format : " + format);
            //            ByteBuffer csd = format.getByteBuffer("csd-0");
            //            if(csd == null){
            //            Log.v("", "csd is null");
            //            } else{
            //               Log.v("", "csd is not null");
            //            }
            //            for (int k = 0; k < csd.capacity(); ++k) {
            //               Log.v("", "inside for loop 1");
            //               Log.e("TAG", "csd : " + csd.array()[k]);
            //            }
            sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
            channel = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
            break;
        }
    }
    //      MediaFormat format = makeAACCodecSpecificData(MediaCodecInfo.CodecProfileLevel.AACObjectLC, mSampleRate, channel);
    //      if (format == null)
    //         return;
    int countt = 0;
    boolean found = false;
    MediaFormat format = null;
    String mime = null;

    while (countt < extractor.getTrackCount() && !found) {
        format = extractor.getTrackFormat(countt);
        mime = format.getString(MediaFormat.KEY_MIME);
        sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        if (mime.startsWith("audio/")) {
            found = true;
        }
        countt++;
    }
    //format = mExtractor.getTrackFormat(count);
    //MediaCodecInfo codec = selectCodec(mime);
    //String name = codec.getName();
    MediaCodec decoder = MediaCodec.createDecoderByType(mime);

    //mDecoder = MediaCodec.createDecoderByType("audio/mp4a-latm");
    decoder.configure(format, null, null, 0);

    if (decoder == null) {
        Log.e("DecodeActivity", "Can't find video info!");
        return;
    }

    decoder.start();

    Log.v("", "Break Point 2");

    // Get decoded bytes

    ByteBuffer[] inputBuffers = decoder.getInputBuffers();
    ByteBuffer[] outputBuffers = decoder.getOutputBuffers();

    BufferInfo info = new BufferInfo();

    //      int buffsize = AudioTrack.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
    //        // create an audiotrack object
    //      AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
    //                AudioFormat.CHANNEL_OUT_STEREO,
    //                AudioFormat.ENCODING_PCM_16BIT,
    //                buffsize,
    //                AudioTrack.MODE_STREAM);
    //      audioTrack.play();

    extractor.seekTo(WINDOW_START, MediaExtractor.SEEK_TO_CLOSEST_SYNC);

    long start = SystemClock.elapsedRealtimeNanos();

    Log.v("", "Break Point 3");

    // MUSICAL SURFACE FEATURES

    double[] flux = new double[NUM_CHUNKS];
    double[] zeroCrossings = new double[NUM_CHUNKS];
    double[] centroid = new double[NUM_CHUNKS];
    int[] rolloff = new int[NUM_CHUNKS];
    double[] rolloffFreq = new double[NUM_CHUNKS];
    double lowEnergy = 0.0;

    // Means across all chunks
    double fluxMean = 0.0;
    double zeroCrossingsMean = 0;
    double centroidMean = 0.0;
    double rolloffMean = 0;

    // Standard deviations across all chunks
    double fluxStdDeviation = 0.0;
    double zeroCrossingsStdDeviation = 0;
    double centroidStdDeviation = 0.0;
    double rolloffStdDeviation = 0;

    // Initialise some variables to use while iterating
    double[] fftSums = new double[NUM_CHUNKS];
    int iter = 0;
    int count = 0;
    FastFourierTransformer transformer = new FastFourierTransformer(DftNormalization.STANDARD);
    double po2 = 0.0;
    Complex[] input = null;
    Complex[] output = null;
    Complex[] previousOutput = null;
    Complex[] temp = null;
    double frequency = 0.0;
    double centroidNum = 0.0;
    double centroidDen = 0.0;
    double fftValue = 0.0;
    double fftPrevious = 0.0;
    double fluxSquared = 0.0;
    int r = 0;
    boolean foundRolloff = false;
    double sum = 0;
    ArrayList<Double> data = new ArrayList<Double>();
    ArrayList<Double> currentChunk = new ArrayList<Double>();
    int gap = 0;
    int tempCount = 0;
    byte[] chunk = null;
    ArrayList<Double> outputExample = new ArrayList<Double>();
    double normConst = 0.0;

    // Iterate through the chunks
    Log.v("", "count: " + String.valueOf(count));
    while (!eosReceived && count < NUM_CHUNKS) {
        Log.v("", "Break Point " + String.valueOf(count + 4));
        Log.v("", "Inside While Loop Break Point 1");
        if (count == 0) {
            //   Log.v("", "Timestamp of chunk 0: " + String.valueOf(extractor.getSampleTime()));
        }

        int inIndex = decoder.dequeueInputBuffer(TIMEOUT_US);
        if (inIndex >= 0) {
            ByteBuffer buffer = inputBuffers[inIndex];
            int sampleSize = extractor.readSampleData(buffer, 0);
            if (sampleSize < 0) {
                // We shouldn't stop the playback at this point, just pass the EOS
                // flag to mDecoder, we will get it again from the
                // dequeueOutputBuffer
                //Log.d("DecodeActivity", "InputBuffer BUFFER_FLAG_END_OF_STREAM");
                decoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);

            } else {
                decoder.queueInputBuffer(inIndex, 0, sampleSize, extractor.getSampleTime(), 0);
                extractor.advance();
            }

            int outIndex = decoder.dequeueOutputBuffer(info, TIMEOUT_US);
            Log.v("", "Inside While Loop Break Point 2");
            switch (outIndex) {
            case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
                Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
                outputBuffers = decoder.getOutputBuffers();
                break;

            case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
                MediaFormat mediaFormat = decoder.getOutputFormat();
                Log.d("DecodeActivity", "New format " + mediaFormat);
                //   audioTrack.setPlaybackRate(mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));

                break;
            case MediaCodec.INFO_TRY_AGAIN_LATER:
                Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
                break;

            default:

                Log.v("", "Inside While Loop Break Point 3");
                ByteBuffer outBuffer = outputBuffers[outIndex];
                //Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + outBuffer);

                chunk = new byte[info.size];
                if (chunk.length == 0) {
                    continue;
                }
                outBuffer.get(chunk); // Read the buffer all at once
                outBuffer.clear(); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN

                gap = chunk.length / DOWN_FACTOR;
                currentChunk.clear();
                Log.v("", "Inside While Loop Break Point 4a");
                // ZERO CROSSINGS

                int increment = 1;
                if (chunk.length > 1000) {
                    increment = (int) ((double) chunk.length / ((double) 1000));
                }

                // Downsampling
                for (int i = 0; i < chunk.length; i = i + increment) {
                    data.add((double) chunk[i]);
                    currentChunk.add((double) chunk[i]);
                    tempCount++;

                    if (currentChunk.size() > 1) {
                        iter += FastMath.abs(sign(currentChunk.get(currentChunk.size() - 1))
                                - sign(currentChunk.get(currentChunk.size() - 2)));

                    }
                }
                increment = 0;

                tempCount = 0;
                zeroCrossings[count] = 0.5 * iter;

                po2 = FastMath.ceil(FastMath.log(currentChunk.size()) / FastMath.log(2));
                input = new Complex[(int) (FastMath.pow(2.0, po2))];

                Log.v("", "chunk length: " + chunk.length);
                Log.v("", "input length: " + input.length);
                for (int i = 0; i < input.length; i++) {
                    if (i < currentChunk.size()) {
                        input[i] = new Complex((double) currentChunk.get(i));
                    } else {
                        input[i] = new Complex(0.0);
                    }
                }

                // FFT
                output = transformer.transform(input, TransformType.FORWARD);

                outputExample.add(centroidDen);

                // CENTROID AND FLUX      

                for (int i = 0; i < output.length; i++) {

                    if (count > 0) {
                        fftPrevious = fftValue;
                    }
                    fftValue = FastMath.hypot(output[i].getReal(), output[i].getImaginary());
                    fluxSquared += (fftValue - fftPrevious) * (fftValue - fftPrevious);

                    centroidNum += i * fftValue;
                    centroidDen += fftValue;

                }

                //               for(int i = 0; i < output.length; i++){
                //                  
                //                  normConst += FastMath.hypot(output[i].getReal(), output[i].getImaginary()) *
                //                        FastMath.hypot(output[i].getReal(), output[i].getImaginary());
                //                  
                //                  
                //               }

                //               fluxSquared = fluxSquared / normConst;
                flux[count] = FastMath.sqrt(fluxSquared) / 1000.0;

                // ROLLOFF

                while (!foundRolloff && r < output.length - 1) {
                    r++;
                    sum += FastMath.hypot(output[r].getReal(), output[r].getImaginary());
                    foundRolloff = checkRolloff(ROLLOFF_PROPORTIONAL_ERROR, sum, centroidDen);
                }

                fftSums[count] = centroidDen;
                if (centroidDen != 0.0) {
                    centroid[count] = centroidNum / centroidDen;
                } else {
                    centroid[count] = 0.0;
                }
                rolloff[count] = r;

                iter = 0;
                fluxSquared = 0.0;
                centroidNum = 0.0;
                centroidDen = 0.0;
                r = 0;
                sum = 0.0;
                foundRolloff = false;
                count++;
                //audioTrack.write(chunk, info.offset, info.offset + info.size); // AudioTrack write data
                decoder.releaseOutputBuffer(outIndex, false);

                break;
            }

            // All decoded frames have been rendered, we can stop playing now
            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
                break;
            }

            if (count > 0) {
                previousOutput = output;
                output = null;
            }
        }
        if (count == NUM_CHUNKS) {
            //   Log.v("", "Timestamp of last chunk: " + String.valueOf(extractor.getSampleTime()));
            decoder.stop();
            decoder.release();
            extractor.release();
        }

    } // while loop

    currentChunk.clear();
    currentChunk = null;

    //      for(int i = 0; i < centroid.length; i++){
    //      Log.v("", "centroid: " + String.valueOf(centroid[i]));
    //      }
    double energySum = 0.0;
    double energyAverage = 0.0;
    int lowEnergyCount = 0;

    for (int i = 0; i < NUM_CHUNKS; i++) {
        energySum += fftSums[i];
    }

    energyAverage = energySum / NUM_CHUNKS;
    for (int i = 0; i < NUM_CHUNKS; i++) {
        if (fftSums[i] < energyAverage) {
            lowEnergyCount++;
        }
    }

    lowEnergy = 100.0 * (((double) lowEnergyCount) / ((double) NUM_CHUNKS));

    // Work out the means and standard deviations

    for (int i = 0; i < NUM_CHUNKS; i++) {

        fluxMean += flux[i];
        zeroCrossingsMean += zeroCrossings[i];
        centroidMean += centroid[i];
        rolloffMean += rolloff[i];

    }

    fluxMean = fluxMean / flux.length;
    zeroCrossingsMean = zeroCrossingsMean / zeroCrossings.length;
    centroidMean = centroidMean / centroid.length;
    rolloffMean = rolloffMean / rolloff.length;

    for (int i = 0; i < NUM_CHUNKS; i++) {

        fluxStdDeviation += (flux[i] - fluxMean) * (flux[i] - fluxMean);
        zeroCrossingsStdDeviation += (zeroCrossings[i] - zeroCrossingsMean)
                * (zeroCrossings[i] - zeroCrossingsMean);
        centroidStdDeviation += (centroid[i] - centroidMean) * (centroid[i] - centroidMean);
        rolloffStdDeviation += (rolloff[i] - rolloffMean) * (rolloff[i] - rolloffMean);

    }

    fluxStdDeviation = Math.sqrt(fluxStdDeviation / flux.length);
    zeroCrossingsStdDeviation = Math.sqrt(zeroCrossingsStdDeviation / zeroCrossings.length);
    centroidStdDeviation = Math.sqrt(centroidStdDeviation / centroid.length);
    rolloffStdDeviation = Math.sqrt(rolloffStdDeviation / rolloff.length);

    Log.v("", "fluxMean: " + String.valueOf(fluxMean));
    Log.v("", "zeroCrossingsMean: " + String.valueOf(zeroCrossingsMean));
    Log.v("", "centroidMean: " + String.valueOf(centroidMean));
    Log.v("", "rolloffMean: " + String.valueOf(rolloffMean));

    Log.v("", "fluxStdDeviation: " + String.valueOf(fluxStdDeviation));
    Log.v("", "zeroCrossingsStdDeviation: " + String.valueOf(zeroCrossingsStdDeviation));
    Log.v("", "centroidStdDeviation: " + String.valueOf(centroidStdDeviation));
    Log.v("", "rolloffStdDeviation: " + String.valueOf(rolloffStdDeviation));

    Log.v("", "lowEnergy: " + String.valueOf(lowEnergy));

    Log.v("", "data size: " + String.valueOf(data.size()));

    // BEAT ANALYSIS

    Transform t = new Transform(new FastWaveletTransform(new Daubechies4()));

    double[] dataArray = new double[data.size()];
    for (int i = 0; i < data.size(); i++) {
        dataArray[i] = data.get(i);
    }
    data.clear();
    data = null;

    double powerOf2 = FastMath.ceil(FastMath.log(chunk.length) / FastMath.log(2));
    double[] dataArrayPo2 = Arrays.copyOf(dataArray, (int) (FastMath.pow(2.0, powerOf2)));
    dataArray = null;

    double[] dataCurrentInputArray = null;
    double[] dataCurrentOutputArray = null;
    double[] dataCumulativeArray = new double[dataArrayPo2.length];
    for (int i = 0; i < dataCumulativeArray.length; i++) {
        dataCumulativeArray[i] = 0.0;
    }
    double temp1 = 0.0;
    double temp2 = 0.0;
    ArrayList<Double> tempList = new ArrayList<Double>();
    int k = 16; // Downsampling factor
    int tempCount1 = 0;
    double mean = 0.0;
    for (int level = 0; level < (int) FastMath.log(2.0, dataArrayPo2.length); level++) {

        dataCurrentInputArray = t.forward(dataArrayPo2, level);
        dataCurrentOutputArray = dataCurrentInputArray;
        dataCurrentOutputArray[0] = 0.0;
        for (int i = 1; i < dataCurrentOutputArray.length; i++) {
            temp1 = FastMath.abs(dataCurrentInputArray[i]); // Full-wave rectification
            dataCurrentOutputArray[i] = (1.0 - ALPHA) * temp1 - ALPHA * dataCurrentOutputArray[i - 1]; // Low-pass filtering
        }
        tempCount1 = 0;
        mean = 0.0;
        while (k * tempCount1 < dataCurrentOutputArray.length) {
            tempList.add(dataCurrentOutputArray[k * tempCount1]); // Downsampling by k
            mean += dataCurrentOutputArray[k * tempCount1];
            tempCount1++;
        }
        mean = mean / dataCurrentOutputArray.length;

        tempCount1 = 0;
        while (k * tempCount1 < dataCurrentOutputArray.length) {
            dataCumulativeArray[k * tempCount1] += tempList.get(tempCount1) - mean; // Mean removal
            tempCount1++;
        }

    }
    int N = dataCumulativeArray.length;
    ArrayList<Double> dataList = new ArrayList<Double>();
    double dataElement = 0.0;

    for (int i = 0; i < N; i++) {
        if (dataCumulativeArray[i] != 0.0) {
            dataElement = autocorrelate(i, N, dataCumulativeArray);
            dataList.add(dataElement);
            Log.v("", "dataList: " + String.valueOf(dataElement));
        }
    }

    PeakDetector peakDetector = new PeakDetector(dataList);
    int[] peakIndices = peakDetector.process(5, 2);
    HashSet<Integer> hs = new HashSet<Integer>();
    for (int i = 0; i < peakIndices.length; i++) {
        hs.add(peakIndices[i]);
    }
    ArrayList<Integer> indicesList = new ArrayList<Integer>();
    ArrayList<Double> valuesList = new ArrayList<Double>();

    indicesList.addAll(hs);
    Double tempDoub = 0.0;

    HashMap<Double, Integer> hm = new HashMap<Double, Integer>();
    for (int i = 0; i < indicesList.size(); i++) {
        tempDoub = dataList.get(indicesList.get(i));
        hm.put(tempDoub, indicesList.get(i));
    }

    indicesList.clear();
    valuesList.clear();

    Entry<Double, Integer> tempEntry = null;
    Iterator<Entry<Double, Integer>> it = hm.entrySet().iterator();
    while (it.hasNext()) {
        tempEntry = (Entry<Double, Integer>) it.next();
        if (tempEntry.getValue() < 75) {
            it.remove();
        } else {
            //indicesList.add(tempEntry.getValue());
            valuesList.add(tempEntry.getKey());
        }
    }

    Collections.sort(valuesList);
    for (int i = 0; i < valuesList.size(); i++) {
        indicesList.add(hm.get(valuesList.get(i)));
    }

    double valuesSum = 0.0;
    double histogramSum = 0.0;

    double beatStrength = 0.0;
    double P1 = 0.0;
    double P2 = 0.0;
    double A1 = 0.0;
    double A2 = 0.0;
    double RA = 0.0;

    for (int i = 0; i < dataList.size(); i++) {
        histogramSum += dataList.get(i);
    }

    for (int i = 0; i < valuesList.size(); i++) {
        valuesSum += valuesList.get(i);
    }

    //      if(histogramSum != 0.0 && valuesList.size() != 0){
    //         SUM = (1000.0 * valuesSum) / (histogramSum * valuesList.size());
    //      }
    if (valuesList.size() != 0) {
        beatStrength = valuesSum / valuesList.size();
    }

    if (indicesList.size() > 0) {

        // Set P1 as the largest peak
        P1 = (double) indicesList.get(indicesList.size() - 1);

    }

    if (indicesList.size() > 1) {
        int beatCount = indicesList.size() - 2;
        boolean beatFound = false;

        // Start with P2 as the second largest peak
        P2 = (double) indicesList.get(indicesList.size() - 2);
        double diff = 0;

        // Iterate backwards through the peaks, largest to smallest
        while (!beatFound && beatCount > -1) {
            diff = ((double) indicesList.get(beatCount)) - P1;

            if (FastMath.abs(diff) / P1 > 0.3) {
                // Set P2 as the period of the first peak that is reasonably different from P1
                P2 = (double) indicesList.get(beatCount);
                beatFound = true;
            }
            beatCount--;
        }
    }

    if (indicesList.size() > 0) {

        A1 = FastMath.abs(dataList.get((int) P1)) / histogramSum;
        if (P2 != 0.0) {
            A2 = FastMath.abs(dataList.get((int) P2)) / histogramSum;
        }

        if (A1 != 0.0) {
            RA = A2 / A1;

        }
    }

    for (int i = 0; i < valuesList.size(); i++) {
        Log.v("", String.valueOf(i) + ") valuesList: " + String.valueOf(valuesList.get(i)));
    }
    Log.v("", "P1: " + String.valueOf(P1));
    Log.v("", "P2: " + String.valueOf(P2));
    Log.v("", "A1: " + String.valueOf(A1));
    Log.v("", "A2: " + String.valueOf(A2));
    Log.v("", "RA: " + String.valueOf(RA));
    Log.v("", "SUM: " + String.valueOf(histogramSum));
    Log.v("", "Number of Peaks: " + String.valueOf(valuesList.size()));
    double[] result = { fluxMean, zeroCrossingsMean, centroidMean, rolloffMean, fluxStdDeviation,
            zeroCrossingsStdDeviation, centroidStdDeviation, rolloffStdDeviation, lowEnergy, P1, P2, A1, A2, RA,
            histogramSum, valuesList.size() };
    final DenseInstance denseInstance = new DenseInstance(result);
    if (P1 + P2 + A1 + A2 + RA != 0.0) {
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new ReturnResultsRunnable(lock, mAudioCallback, denseInstance, classLabel));

    } else {
        Log.v("", "Track could not be classified!");
    }

    //      for(int i = 0; i < dataList.size(); i++){
    //         Log.v("", String.valueOf(i) + ") autocorrelation: " + String.valueOf(dataList.get(i)));
    //         histogramSum += dataList.get(i);
    //      }
    //      Log.v("", "indicesList size: " + String.valueOf(indicesList.size()));
    //      for(int i = 0; i < valuesList.size(); i++){
    //         Log.v("", "indicesList: " + String.valueOf(indicesList.get(i)) + ", value: " + String.valueOf(valuesList.get(i)));
    //         valuesSum += valuesList.get(i);
    //      }
    //Classifier c = new KNearestNeighbors(5);

    //      double A0 = valuesList.get(valuesList.size() - 1) / valuesSum;
    //      double A1 = valuesList.get(valuesList.size() - 2) / valuesSum;
    //      double RA = A1 / A0;
    //      double P0 = 1 / ((double) indicesList.get(indicesList.size() - 1));
    //      double P1 = 1 / ((double) indicesList.get(indicesList.size() - 2));
    //      
    //      Log.v("", "A0: " + String.valueOf(A0));
    //      Log.v("", "A1: " + String.valueOf(A1));
    //      Log.v("", "RA: " + String.valueOf(RA));
    //      Log.v("", "P0: " + String.valueOf(P0));
    //      Log.v("", "P1: " + String.valueOf(P1));
    //      Log.v("", "SUM: " + String.valueOf(histogramSum));

    long durationUs = SystemClock.elapsedRealtimeNanos() - start;
    double durationSecs = ((double) durationUs) / 1000000000.0;
    Log.v("", "count = " + String.valueOf(count) + ", Sample rate: " + String.valueOf(sampleRate)
            + ", Duration: " + String.valueOf(durationSecs));

    //      audioTrack.stop();
    //      audioTrack.release();
    //      audioTrack = null;
}

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

@Override
protected boolean parseBox(BoxHeader header) {
    if (header == null) {
        return false;
    }//from  www  .j  a  v  a2  s.  c o m
    mCurrentBoxSequence.add(header);
    long boxEndOffset = mCurrentOffset + header.boxDataSize;
    boolean parseOK = true;
    if (header.boxType == BOX_ID_FTYP) {
        int majorBrand;
        try {
            majorBrand = mDataSource.readInt();
            if (majorBrand == FTYP_BRAND_MGSV) {
                mIsMarlinProtected = true;
            }
        } catch (EOFException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Exception parsing 'ftyp' box", e);
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Exception parsing 'ftyp' box", e);
        }
    } else if (header.boxType == BOX_ID_UUID) {
        byte[] userType = new byte[16];
        try {
            mDataSource.read(userType);
            mCurrentOffset += 16;
            String uuidUserType = Util.bytesToHex(userType);
            if (uuidUserType.equals(UUID_PROF)) {
                parseOK = parseUuidPROF(header);
            } else if (uuidUserType.equals(UUID_MTSD)) {
                // MTSD box
                mMtsdOffset = header.startOffset;
                mNeedsMTSD = false;
            } else if (uuidUserType.equals(UUID_USMT)) {
                // USMT box
                while (mCurrentOffset < boxEndOffset && parseOK) {
                    BoxHeader nextBoxHeader = getNextBoxHeader();
                    parseOK = parseBox(nextBoxHeader);
                }
            } else {
                mCurrentOffset -= 16;
                parseOK = super.parseBox(header);
            }
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Error parsing 'uuid' box", e);
            parseOK = false;
        }
    } else if (header.boxType == BOX_ID_MTDT) {
        parseOK = parseMtdt(header);
    } else if (header.boxType == BOX_ID_MTSM) {
        if (mMtsmList == null) {
            mMtsmList = new ArrayList<MtsmEntry>();
        }
        mCurrentMtsmEntry = new MtsmEntry();
        while (mCurrentOffset < boxEndOffset && parseOK) {
            BoxHeader nextBoxHeader = getNextBoxHeader();
            parseOK = parseBox(nextBoxHeader);
        }
        mMtsmList.add(mCurrentMtsmEntry);
    } else if (header.boxType == BOX_ID_MTHD) {
        try {
            mDataSource.skipBytes(12);
            mCurrentMtsmEntry.id = mDataSource.readInt();
            mDataSource.skipBytes(8);
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Exception reading 'MTHD' box", e);
        }
    } else if (header.boxType == BOX_ID_MDST) {
        try {
            mDataSource.skipBytes(4);
            int metadataSampleCount = mDataSource.readInt();
            mCurrentMtsmEntry.mMdstList = new ArrayList<MdstEntry>(metadataSampleCount);
            for (int i = 0; i < metadataSampleCount; i++) {
                MdstEntry mdstEntry = new MdstEntry();
                mdstEntry.metadataSampleDescriptionIndex = mDataSource.readInt();
                mdstEntry.metadataSampleOffset = mDataSource.readInt();
                mdstEntry.metadataSampleSize = mDataSource.readInt();
                mDataSource.skipBytes(8);
                mCurrentMtsmEntry.mMdstList.add(mdstEntry);
            }
            mNeedsMTSD = true;
        } catch (EOFException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Exception reading from 'MDST' box", e);
        } catch (IOException e) {
            if (LOGS_ENABLED)
                Log.e(TAG, "Exception reading from 'MDST' box", e);
        }
    } else if (header.boxType == BOX_ID_STGS) {
        MediaFormat mediaFormat = MediaFormat.createSubtitleFormat("subtitle/grap-text",
                mCurrentTrack.getLanguage());
        mCurrentTrack.addSampleDescriptionEntry(mediaFormat);

        mCurrentTrack.getMetaData().addValue(KEY_MIME_TYPE, mediaFormat.getString(MediaFormat.KEY_MIME));
    } 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;
        }

        if (mIsMarlinProtected) {
            ByteBuffer buffer = parseAvccForMarlin(data);
            if (buffer == null) {
                return false;
            }
            mCurrentMediaFormat.setByteBuffer("csd-0", buffer);

            parseSPS(buffer.array());
        } else {
            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);

            parseSPS(avccData.spsBuffer.array());
        }
    } else if (header.boxType == BOX_ID_MDAT) {
        if (mTracks.size() > 0 && !mIsFragmented && !mNeedsMTSD) {
            mInitDone = true;
        } else if (mIsFragmented && mFirstMoofOffset != -1) {
            mInitDone = true;
        } else {
            mMdatFound = true;
        }
    } else {
        parseOK = super.parseBox(header);
    }
    mCurrentOffset = boxEndOffset;
    mCurrentBoxSequence.removeLast();
    return parseOK;
}

From source file:com.nagravision.mediaplayer.FullscreenActivity.java

/**
 *
 *//*from   w  w w  .j  a  v a2 s  . co m*/
@SuppressWarnings("unused")
private void ClickItem(int position, int msec) {
    Log.v(LOG_TAG, "FullscreenActivity::ClickItem - Enter\n");

    /* Close the drawer */
    mDrawer.closeDrawers();

    /* Build the notification we are going to display */
    mNotifBuilder.setContentText(getResources().getString(R.string.playing_notification));
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    (new PrintWriter(baos)).format(getResources().getString(R.string.long_playing_notification),
            MOVIES_ARR[position]);
    mNotifBuilder.setContentInfo(baos.toString());
    mNotifBuilder.setContentTitle(getResources().getString(R.string.app_name));
    mNotifBuilder.setSubText(getResources().getString(R.string.app_copyright));
    mNotifBuilder.setSmallIcon(R.drawable.ic_action_play);
    mExplicitIntent.setData(Uri.parse(MOVIES_URLS[position]));
    mNotifBuilder.setContentIntent(mDefaultIntent);
    mNotifBuilder.addAction(R.drawable.ic_action_about,
            getResources().getString(R.string.infos_action_description), mInfosIntent);

    /* If a notif was already sent, cancel it */
    if (mLastNotif != null) {
        if (mLastPosition != -1) {
            mNotifMgr.cancel(getResources().getString(R.string.playing_notification), mLastPosition);
            mLastPosition = -1;
        } else
            mNotifMgr.cancelAll();
        mLastNotif = null;
    }
    mLastNotif = mNotifBuilder.build();
    mLastPosition = position;

    if (false && MOVIES_MDTA[position].contains("drm")) {
        Log.d(LOG_TAG, "Starting extraction of Media Metadata\n");
        MediaExtractor extractor = new MediaExtractor();
        try {
            Log.d(LOG_TAG, "URL: " + MOVIES_URLS[position]);
            extractor.setDataSource(MOVIES_URLS[position]);
            int numTracks = extractor.getTrackCount();
            Log.v(LOG_TAG, "Number of tracks: " + numTracks);
            for (int i = 0; i < numTracks; ++i) {
                MediaFormat format = extractor.getTrackFormat(i);
                String mime = format.getString(MediaFormat.KEY_MIME);
                Log.v(LOG_TAG, "Track[" + i + "].mime = " + mime);
                if (mime.equals("video/avc")) {
                    extractor.selectTrack(i);
                    //                        byte[] key = new byte[16];
                    //                        key[0] = (byte) 0x7f; key[1] = (byte) 0x99; key[2] = (byte) 0x06; key[3] = (byte) 0x95;
                    //                        key[4] = (byte) 0x78; key[5] = (byte) 0xab; key[6] = (byte) 0x4d; key[7] = (byte) 0xae;
                    //                        key[8] = (byte) 0x8d; key[9] = (byte) 0x6c; key[10] = (byte) 0xe2; key[11] = (byte) 0x4c;
                    //                        key[12] = (byte) 0xc3; key[13] = (byte) 0x21; key[14] = (byte) 0x02; key[15] = (byte) 0x32;
                    MediaCrypto mediaCrypto;
                    MediaCodec codec = MediaCodec.createDecoderByType("video/avc");
                    Map<UUID, byte[]> psshInfo = extractor.getPsshInfo();
                    for (Iterator<UUID> it = psshInfo.keySet().iterator(); it.hasNext();) {
                        UUID uuid = it.next();
                        String psshData = new String(psshInfo.get(uuid));
                        Log.v(LOG_TAG, "PSSH for UUID: " + uuid.toString() + " has data :" + psshData);
                        try {
                            mediaCrypto = new MediaCrypto(uuid, psshInfo.get(uuid));
                            codec.configure(format, mVideoHolder.getHolder().getSurface(), mediaCrypto, 0);
                            codec.start();
                            @SuppressWarnings("unused")
                            ByteBuffer[] inputBuffers = codec.getInputBuffers();
                            @SuppressWarnings("unused")
                            ByteBuffer[] outputBuffers = codec.getOutputBuffers();
                            for (;;) {
                                int inputBufferIndex = codec.dequeueInputBuffer(200000);
                                if (inputBufferIndex >= 0) {
                                    //extractor.readSampleData();
                                    Log.v(LOG_TAG,
                                            "Read data from extractor (and crypto) and provide to decoder\n");
                                }
                            }
                        } catch (MediaCryptoException mce) {
                            Log.e(LOG_TAG, "Could not instanciate MediaCrypto ! " + mce);
                        }
                    }
                }
            }
        } catch (IOException ioe) {
            Log.e(LOG_TAG, "Cannot access URL: " + ioe);
        }
    }

    /* Setup media player for playing the movie */
    mVideoHolder.setVideoURI(Uri.parse(MOVIES_URLS[position]));
    mVideoHolder.requestFocus();
    mVideoHolder.start();

    if (msec > 0) {
        if (mVideoHolder.canPause())
            mVideoHolder.pause();
        mVideoHolder.seekTo(msec);
        if (mVideoHolder.canPause())
            mVideoHolder.resume();
    }

    /* Player has started ... send notification */
    mNotifMgr.notify(getResources().getString(R.string.playing_notification), mLastPosition, mLastNotif);
}

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

protected boolean parseBox(BoxHeader header) {
    if (header == null) {
        return false;
    }// w ww  . j a v  a 2 s  .  c om
    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 String asString(final MediaFormat format) {
    final JSONObject map = new JSONObject();
    try {/* w  w  w  .j ava 2s  .  c o  m*/
        if (format.containsKey(MediaFormat.KEY_MIME))
            map.put(MediaFormat.KEY_MIME, format.getString(MediaFormat.KEY_MIME));
        if (format.containsKey(MediaFormat.KEY_WIDTH))
            map.put(MediaFormat.KEY_WIDTH, format.getInteger(MediaFormat.KEY_WIDTH));
        if (format.containsKey(MediaFormat.KEY_HEIGHT))
            map.put(MediaFormat.KEY_HEIGHT, format.getInteger(MediaFormat.KEY_HEIGHT));
        if (format.containsKey(MediaFormat.KEY_BIT_RATE))
            map.put(MediaFormat.KEY_BIT_RATE, format.getInteger(MediaFormat.KEY_BIT_RATE));
        if (format.containsKey(MediaFormat.KEY_COLOR_FORMAT))
            map.put(MediaFormat.KEY_COLOR_FORMAT, format.getInteger(MediaFormat.KEY_COLOR_FORMAT));
        if (format.containsKey(MediaFormat.KEY_FRAME_RATE))
            map.put(MediaFormat.KEY_FRAME_RATE, format.getInteger(MediaFormat.KEY_FRAME_RATE));
        if (format.containsKey(MediaFormat.KEY_I_FRAME_INTERVAL))
            map.put(MediaFormat.KEY_I_FRAME_INTERVAL, format.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL));
        if (format.containsKey(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER))
            map.put(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER,
                    format.getLong(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER));
        if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE))
            map.put(MediaFormat.KEY_MAX_INPUT_SIZE, format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE));
        if (format.containsKey(MediaFormat.KEY_DURATION))
            map.put(MediaFormat.KEY_DURATION, format.getInteger(MediaFormat.KEY_DURATION));
        if (format.containsKey(MediaFormat.KEY_CHANNEL_COUNT))
            map.put(MediaFormat.KEY_CHANNEL_COUNT, format.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
        if (format.containsKey(MediaFormat.KEY_SAMPLE_RATE))
            map.put(MediaFormat.KEY_SAMPLE_RATE, format.getInteger(MediaFormat.KEY_SAMPLE_RATE));
        if (format.containsKey(MediaFormat.KEY_CHANNEL_MASK))
            map.put(MediaFormat.KEY_CHANNEL_MASK, format.getInteger(MediaFormat.KEY_CHANNEL_MASK));
        if (format.containsKey(MediaFormat.KEY_AAC_PROFILE))
            map.put(MediaFormat.KEY_AAC_PROFILE, format.getInteger(MediaFormat.KEY_AAC_PROFILE));
        if (format.containsKey(MediaFormat.KEY_AAC_SBR_MODE))
            map.put(MediaFormat.KEY_AAC_SBR_MODE, format.getInteger(MediaFormat.KEY_AAC_SBR_MODE));
        if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE))
            map.put(MediaFormat.KEY_MAX_INPUT_SIZE, format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE));
        if (format.containsKey(MediaFormat.KEY_IS_ADTS))
            map.put(MediaFormat.KEY_IS_ADTS, format.getInteger(MediaFormat.KEY_IS_ADTS));
        if (format.containsKey("what"))
            map.put("what", format.getInteger("what"));
        if (format.containsKey("csd-0"))
            map.put("csd-0", asString(format.getByteBuffer("csd-0")));
        if (format.containsKey("csd-1"))
            map.put("csd-1", asString(format.getByteBuffer("csd-1")));
    } catch (JSONException e) {
        Log.e(TAG_STATIC, "writeFormat:", e);
    }

    return map.toString();
}

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

private static final MediaFormat asMediaFormat(final String format_str) {
    MediaFormat format = new MediaFormat();
    try {/* w w w.j  ava2 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;
}

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

@Override
public TrackInfo[] getTrackInfo() {
    int numTracks = mTracks.size();
    TrackInfo[] trackInfos = new TrackInfo[numTracks];

    for (int i = 0; i < numTracks; i++) {
        IsoTrack track = (IsoTrack) mTracks.get(i);
        TrackType trackType = track.getTrackType();
        if (trackType != TrackType.UNKNOWN) {
            MediaFormat mediaFormat = track.getMediaFormat();
            String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
            long durationUs = track.getDurationUs();
            String language = track.getLanguage();

            TrackRepresentation representation = null;

            if (trackType == TrackType.AUDIO) {
                int channelCount = mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
                int sampleRate = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
                representation = new AudioTrackRepresentation(-1, channelCount, "", sampleRate);
            } else if (trackType == TrackType.VIDEO) {
                int width = mediaFormat.getInteger(MediaFormat.KEY_WIDTH);
                int height = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
                representation = new VideoTrackRepresentation(-1, width, height, -1f);
            } else { // SUBTITLE, UNKNOWN
                representation = new TrackRepresentation(-1);
            }//from w  w  w . j  a v a 2 s .c o  m

            TrackInfo trackInfo = new TrackInfo(trackType, mimeType, durationUs, language);
            TrackRepresentation[] representations = new TrackRepresentation[1];
            representations[0] = representation;
            trackInfo.setRepresentations(representations);
            trackInfos[i] = trackInfo;
        } else {
            trackInfos[i] = new TrackInfo(TrackType.UNKNOWN, "", 0, "");
        }
    }

    return trackInfos;
}