/* * Copyright (C) 2011 in-somnia * * This file is part of JAAD. * * JAAD is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 3 of the * License, or (at your option) any later version. * * JAAD is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. * If not, see <http://www.gnu.org/licenses/>. */ package net.sourceforge.jaad.mp4.boxes.impl; import java.io.IOException; import net.sourceforge.jaad.mp4.MP4InputStream; import net.sourceforge.jaad.mp4.boxes.FullBox; /** * The Sub-Sample Information box is designed to contain sub-sample information. * A sub-sample is a contiguous range of bytes of a sample. The specific * definition of a sub-sample shall be supplied for a given coding system (e.g. * for ISO/IEC 14496-10, Advanced Video Coding). In the absence of such a * specific definition, this box shall not be applied to samples using that * coding system. * The table is sparsely coded; the table identifies which samples have * sub-sample structure by recording the difference in sample-number between * each entry. The first entry in the table records the sample number of the * first sample having sub-sample information. * * @author in-somnia */ public class SubSampleInformationBox extends FullBox { private long[] sampleDelta; private long[][] subsampleSize; private int[][] subsamplePriority; private boolean[][] discardable; public SubSampleInformationBox() { super("Sub Sample Information Box"); } @Override public void decode(MP4InputStream in) throws IOException { super.decode(in); final int len = (version==1) ? 4 : 2; final int entryCount = (int) in.readBytes(4); sampleDelta = new long[entryCount]; subsampleSize = new long[entryCount][]; subsamplePriority = new int[entryCount][]; discardable = new boolean[entryCount][]; int j, subsampleCount; for(int i = 0; i<entryCount; i++) { sampleDelta[i] = in.readBytes(4); subsampleCount = (int) in.readBytes(2); subsampleSize[i] = new long[subsampleCount]; subsamplePriority[i] = new int[subsampleCount]; discardable[i] = new boolean[subsampleCount]; for(j = 0; j<subsampleCount; j++) { subsampleSize[i][j] = in.readBytes(len); subsamplePriority[i][j] = in.read(); discardable[i][j] = (in.read()&1)==1; in.skipBytes(4); //reserved } } } /** * The sample delta for each entry is an integer that specifies the sample * number of the sample having sub-sample structure. It is coded as the * difference between the desired sample number, and the sample number * indicated in the previous entry. If the current entry is the first entry, * the value indicates the sample number of the first sample having * sub-sample information, that is, the value is the difference between the * sample number and zero. * * @return the sample deltas for all entries */ public long[] getSampleDelta() { return sampleDelta; } /** * The subsample size is an integer that specifies the size, in bytes, of a * specific sub-sample in a specific entry. * * @return the sizes of all subsamples */ public long[][] getSubsampleSize() { return subsampleSize; } /** * The subsample priority is an integer specifying the degradation priority * for a specific sub-sample in a specific entry. Higher values indicate * sub-samples which are important to, and have a greater impact on, the * decoded quality. * * @return all subsample priorities */ public int[][] getSubsamplePriority() { return subsamplePriority; } /** * If true, the sub-sample is required to decode the current sample, while * false means the sub-sample is not required to decode the current sample * but may be used for enhancements, e.g., the sub-sample consists of * supplemental enhancement information (SEI) messages. * * @return a list of flags indicating if a specific subsample is discardable */ public boolean[][] getDiscardable() { return discardable; } }