/** * */ package mp4.util.atom; /** * This atom represents the size of each sample in the media. */ public class StszAtom extends LeafAtom { private static final int SAMPLE_SIZE_OFFSET = 4; private static final int ENTRIES_OFFSET = 8; private static final int TABLE_OFFSET = 12; private static final int ENTRY_SIZE = 4; /** * Constructor for stsz atom */ public StszAtom() { super(new byte[]{'s','t','s','z'}); } /** * Copy constructor for stsz atom * @param old the object to copy */ public StszAtom(StszAtom old) { super(old); } /** * Allocate space for the atom's data */ @Override public void allocateData(long numEntries) { long size = TABLE_OFFSET + (numEntries * ENTRY_SIZE); super.allocateData(size); } /** * Get the sample size. If this value is non-zero, then it is the size * of all the samples. If this value is zero, then the atom contains a * table with the size of each sample * @return the sample size entry in the atom */ public long getSampleSize() { return data.getUnsignedInt(SAMPLE_SIZE_OFFSET); } /** * Set the sample size. * @param sampleSize the sample size */ public void setSampleSize(long sampleSize) { data.addUnsignedInt(SAMPLE_SIZE_OFFSET, sampleSize); } /** * Return the number of entries in the table * @return the number of entries in the table */ public long getNumEntries() { return data.getUnsignedInt(ENTRIES_OFFSET); } /** * Set the number of entries in the stsz atom table * @param numEntries the number of entries */ public void setNumEntries(long numEntries) { data.addUnsignedInt(ENTRIES_OFFSET, numEntries); } /** * Return the size of the specified sample. The sample numbers are 1 based. * @param sampleNum the sample numbers * @return the size of the sample */ public long getTableSampleSize(long sampleNum) { if (sampleNum > Integer.MAX_VALUE) { return 0; } return data.getUnsignedInt(TABLE_OFFSET + ((int)(sampleNum - 1)* ENTRY_SIZE)); } /** * Return the size of the specified sample. The sample numbers are 1 based. * @param sampleNum the sample numbers * @return the size of the sample */ public long getSampleSize(long sampleNum) { if (getSampleSize() > 0) return getSampleSize(); else return getTableSampleSize(sampleNum); } /** * Set the sample size for the specified table entry * @param sampleNum the sample number * @param sampleSize the sample size */ public void setTableSampleSize(int sampleNum, long sampleSize) { data.addUnsignedInt(TABLE_OFFSET + ((sampleNum - 1) * ENTRY_SIZE), sampleSize); } /** * Cut the stsz table at the specified sample. Performs the update in place * and fills the rest of the atom with dummy data. * @param sampleNum the sample where the split occurs */ public StszAtom cut(long sampleNum) { StszAtom cutStsz = new StszAtom(); long sampleSize = getSampleSize(); if (sampleSize > 0) { cutStsz.allocateData(0); cutStsz.setSampleSize(sampleSize); cutStsz.setNumEntries(getNumEntries() - sampleNum + 1); } else { long numEntries = getNumEntries(); cutStsz.allocateData(numEntries - sampleNum + 1); cutStsz.setSampleSize(0); cutStsz.setNumEntries(numEntries - sampleNum + 1); int entryNumber = 1; for (long i = sampleNum; i <= numEntries; i++, entryNumber++) { cutStsz.setTableSampleSize(entryNumber, getTableSampleSize(i)); } } return cutStsz; } @Override public void accept(AtomVisitor v) throws AtomException { v.visit(this); } }