Home | History | Annotate | Download | only in sampleentry
      1 /*
      2  * Copyright 2008 CoreMedia AG, Hamburg
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the License);
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an AS IS BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.coremedia.iso.boxes.sampleentry;
     18 
     19 import com.coremedia.iso.IsoTypeReader;
     20 import com.coremedia.iso.IsoTypeWriter;
     21 import com.coremedia.iso.Utf8;
     22 import com.coremedia.iso.boxes.Box;
     23 import com.coremedia.iso.boxes.ContainerBox;
     24 
     25 import java.nio.ByteBuffer;
     26 
     27 /**
     28  * Contains information common to all visual tracks.
     29  * <code>
     30  * <pre>
     31  * class VisualSampleEntry(codingname) extends SampleEntry (codingname){
     32  * unsigned int(16) pre_defined = 0;
     33  * const unsigned int(16) reserved = 0;
     34  * unsigned int(32)[3] pre_defined = 0;
     35  * unsigned int(16) width;
     36  * unsigned int(16) height;
     37  * template unsigned int(32) horizresolution = 0x00480000; // 72 dpi
     38  * template unsigned int(32) vertresolution = 0x00480000; // 72 dpi
     39  * const unsigned int(32) reserved = 0;
     40  * template unsigned int(16) frame_count = 1;
     41  * string[32] compressorname;
     42  * template unsigned int(16) depth = 0x0018;
     43  * int(16) pre_defined = -1;
     44  * }<br>
     45  * </pre>
     46  * </code>
     47  * <p/>
     48  * Format-specific informationis appened as boxes after the data described in ISO/IEC 14496-12 chapter 8.16.2.
     49  */
     50 public class VisualSampleEntry extends SampleEntry implements ContainerBox {
     51     public static final String TYPE1 = "mp4v";
     52     public static final String TYPE2 = "s263";
     53     public static final String TYPE3 = "avc1";
     54 
     55 
     56     /**
     57      * Identifier for an encrypted video track.
     58      *
     59      * @see com.coremedia.iso.boxes.ProtectionSchemeInformationBox
     60      */
     61     public static final String TYPE_ENCRYPTED = "encv";
     62 
     63 
     64     private int width;
     65     private int height;
     66     private double horizresolution = 72;
     67     private double vertresolution = 72;
     68     private int frameCount = 1;
     69     private String compressorname;
     70     private int depth = 24;
     71 
     72     private long[] predefined = new long[3];
     73 
     74     public VisualSampleEntry(String type) {
     75         super(type);
     76     }
     77 
     78     public int getWidth() {
     79         return width;
     80     }
     81 
     82     public int getHeight() {
     83         return height;
     84     }
     85 
     86     public double getHorizresolution() {
     87         return horizresolution;
     88     }
     89 
     90     public double getVertresolution() {
     91         return vertresolution;
     92     }
     93 
     94     public int getFrameCount() {
     95         return frameCount;
     96     }
     97 
     98     public String getCompressorname() {
     99         return compressorname;
    100     }
    101 
    102     public int getDepth() {
    103         return depth;
    104     }
    105 
    106     public void setCompressorname(String compressorname) {
    107         this.compressorname = compressorname;
    108     }
    109 
    110     public void setWidth(int width) {
    111         this.width = width;
    112     }
    113 
    114     public void setHeight(int height) {
    115         this.height = height;
    116     }
    117 
    118     public void setHorizresolution(double horizresolution) {
    119         this.horizresolution = horizresolution;
    120     }
    121 
    122     public void setVertresolution(double vertresolution) {
    123         this.vertresolution = vertresolution;
    124     }
    125 
    126     public void setFrameCount(int frameCount) {
    127         this.frameCount = frameCount;
    128     }
    129 
    130     public void setDepth(int depth) {
    131         this.depth = depth;
    132     }
    133 
    134     @Override
    135     public void _parseDetails(ByteBuffer content) {
    136         _parseReservedAndDataReferenceIndex(content);
    137         long tmp = IsoTypeReader.readUInt16(content);
    138         assert 0 == tmp : "reserved byte not 0";
    139         tmp = IsoTypeReader.readUInt16(content);
    140         assert 0 == tmp : "reserved byte not 0";
    141         predefined[0] = IsoTypeReader.readUInt32(content);     // should be zero
    142         predefined[1] = IsoTypeReader.readUInt32(content);     // should be zero
    143         predefined[2] = IsoTypeReader.readUInt32(content);     // should be zero
    144         width = IsoTypeReader.readUInt16(content);
    145         height = IsoTypeReader.readUInt16(content);
    146         horizresolution = IsoTypeReader.readFixedPoint1616(content);
    147         vertresolution = IsoTypeReader.readFixedPoint1616(content);
    148         tmp = IsoTypeReader.readUInt32(content);
    149         assert 0 == tmp : "reserved byte not 0";
    150         frameCount = IsoTypeReader.readUInt16(content);
    151         int compressornameDisplayAbleData = IsoTypeReader.readUInt8(content);
    152         if (compressornameDisplayAbleData > 31) {
    153             System.out.println("invalid compressor name displayable data: " + compressornameDisplayAbleData);
    154             compressornameDisplayAbleData = 31;
    155         }
    156         byte[] bytes = new byte[compressornameDisplayAbleData];
    157         content.get(bytes);
    158         compressorname = Utf8.convert(bytes);
    159         if (compressornameDisplayAbleData < 31) {
    160             byte[] zeros = new byte[31 - compressornameDisplayAbleData];
    161             content.get(zeros);
    162             //assert Arrays.equals(zeros, new byte[zeros.length]) : "The compressor name length was not filled up with zeros";
    163         }
    164         depth = IsoTypeReader.readUInt16(content);
    165         tmp = IsoTypeReader.readUInt16(content);
    166         assert 0xFFFF == tmp;
    167 
    168         _parseChildBoxes(content);
    169 
    170     }
    171 
    172 
    173     protected long getContentSize() {
    174         long contentSize = 78;
    175         for (Box boxe : boxes) {
    176             contentSize += boxe.getSize();
    177         }
    178         return contentSize;
    179     }
    180 
    181     @Override
    182     protected void getContent(ByteBuffer byteBuffer) {
    183         _writeReservedAndDataReferenceIndex(byteBuffer);
    184         IsoTypeWriter.writeUInt16(byteBuffer, 0);
    185         IsoTypeWriter.writeUInt16(byteBuffer, 0);
    186         IsoTypeWriter.writeUInt32(byteBuffer, predefined[0]);
    187         IsoTypeWriter.writeUInt32(byteBuffer, predefined[1]);
    188         IsoTypeWriter.writeUInt32(byteBuffer, predefined[2]);
    189 
    190         IsoTypeWriter.writeUInt16(byteBuffer, getWidth());
    191         IsoTypeWriter.writeUInt16(byteBuffer, getHeight());
    192 
    193         IsoTypeWriter.writeFixedPont1616(byteBuffer, getHorizresolution());
    194         IsoTypeWriter.writeFixedPont1616(byteBuffer, getVertresolution());
    195 
    196 
    197         IsoTypeWriter.writeUInt32(byteBuffer, 0);
    198         IsoTypeWriter.writeUInt16(byteBuffer, getFrameCount());
    199         IsoTypeWriter.writeUInt8(byteBuffer, Utf8.utf8StringLengthInBytes(getCompressorname()));
    200         byteBuffer.put(Utf8.convert(getCompressorname()));
    201         int a = Utf8.utf8StringLengthInBytes(getCompressorname());
    202         while (a < 31) {
    203             a++;
    204             byteBuffer.put((byte) 0);
    205         }
    206         IsoTypeWriter.writeUInt16(byteBuffer, getDepth());
    207         IsoTypeWriter.writeUInt16(byteBuffer, 0xFFFF);
    208 
    209         _writeChildBoxes(byteBuffer);
    210 
    211     }
    212 
    213 }
    214