1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.googlecode.mp4parser.authoring.tracks; 2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.boxes.*; 4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.boxes.h264.AvcConfigurationBox; 5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.coremedia.iso.boxes.sampleentry.VisualSampleEntry; 6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.authoring.AbstractTrack; 7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.authoring.TrackMetaData; 8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.h264.model.PictureParameterSet; 9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.h264.model.SeqParameterSet; 10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport com.googlecode.mp4parser.h264.read.CAVLCReader; 11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.ByteArrayInputStream; 13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.IOException; 14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.io.InputStream; 15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.nio.ByteBuffer; 16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.ArrayList; 17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.Date; 18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.LinkedList; 19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.List; 20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.util.logging.Logger; 21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu/** 23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * The <code>H264TrackImpl</code> creates a <code>Track</code> from an H.264 24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu * Annex B file. 25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu */ 26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class H264TrackImpl extends AbstractTrack { 27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private static final Logger LOG = Logger.getLogger(H264TrackImpl.class.getName()); 28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu TrackMetaData trackMetaData = new TrackMetaData(); 30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu SampleDescriptionBox sampleDescriptionBox; 31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private ReaderWrapper reader; 33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private List<ByteBuffer> samples; 34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu boolean readSamples = false; 35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<TimeToSampleBox.Entry> stts; 37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<CompositionTimeToSample.Entry> ctts; 38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<SampleDependencyTypeBox.Entry> sdtp; 39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu List<Integer> stss; 40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu SeqParameterSet seqParameterSet = null; 42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu PictureParameterSet pictureParameterSet = null; 43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LinkedList<byte[]> seqParameterSetList = new LinkedList<byte[]>(); 44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LinkedList<byte[]> pictureParameterSetList = new LinkedList<byte[]>(); 45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int width; 47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int height; 48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int timescale; 49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int frametick; 50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int currentScSize; 51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private int prevScSize; 52dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 53dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private SEIMessage seiMessage; 54dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int frameNrInGop = 0; 55dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean determineFrameRate = true; 56dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private String lang = "und"; 57dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 58dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public H264TrackImpl(InputStream inputStream, String lang, long timescale) throws IOException { 59dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.lang = lang; 60dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (timescale > 1000) { 61dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu timescale = timescale; //e.g. 23976 62dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frametick = 1000; 63dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu determineFrameRate = false; 64dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 65dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new IllegalArgumentException("Timescale must be specified in milliseconds!"); 66dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 67dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu parse(inputStream); 68dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 69dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 70dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public H264TrackImpl(InputStream inputStream, String lang) throws IOException { 71dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.lang = lang; 72dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu parse(inputStream); 73dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 74dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 75dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public H264TrackImpl(InputStream inputStream) throws IOException { 76dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu parse(inputStream); 77dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 78dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 79dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private void parse(InputStream inputStream) throws IOException { 80dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.reader = new ReaderWrapper(inputStream); 81dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu stts = new LinkedList<TimeToSampleBox.Entry>(); 82dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ctts = new LinkedList<CompositionTimeToSample.Entry>(); 83dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sdtp = new LinkedList<SampleDependencyTypeBox.Entry>(); 84dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu stss = new LinkedList<Integer>(); 85dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 86dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu samples = new LinkedList<ByteBuffer>(); 87dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (!readSamples()) { 88dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new IOException(); 89dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 90dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 91dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (!readVariables()) { 92dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu throw new IOException(); 93dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 94dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 95dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sampleDescriptionBox = new SampleDescriptionBox(); 96dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu VisualSampleEntry visualSampleEntry = new VisualSampleEntry("avc1"); 97dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setDataReferenceIndex(1); 98dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setDepth(24); 99dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setFrameCount(1); 100dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setHorizresolution(72); 101dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setVertresolution(72); 102dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setWidth(width); 103dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setHeight(height); 104dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.setCompressorname("AVC Coding"); 105dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 106dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu AvcConfigurationBox avcConfigurationBox = new AvcConfigurationBox(); 107dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 108dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setSequenceParameterSets(seqParameterSetList); 109dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setPictureParameterSets(pictureParameterSetList); 110dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setAvcLevelIndication(seqParameterSet.level_idc); 111dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setAvcProfileIndication(seqParameterSet.profile_idc); 112dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setBitDepthLumaMinus8(seqParameterSet.bit_depth_luma_minus8); 113dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setBitDepthChromaMinus8(seqParameterSet.bit_depth_chroma_minus8); 114dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setChromaFormat(seqParameterSet.chroma_format_idc.getId()); 115dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setConfigurationVersion(1); 116dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setLengthSizeMinusOne(3); 117dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu avcConfigurationBox.setProfileCompatibility(seqParameterSetList.get(0)[1]); 118dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 119dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu visualSampleEntry.addBox(avcConfigurationBox); 120dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sampleDescriptionBox.addBox(visualSampleEntry); 121dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 122dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu trackMetaData.setCreationTime(new Date()); 123dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu trackMetaData.setModificationTime(new Date()); 124dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu trackMetaData.setLanguage(lang); 125dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu trackMetaData.setTimescale(timescale); 126dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu trackMetaData.setWidth(width); 127dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu trackMetaData.setHeight(height); 128dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 129dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 130dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public SampleDescriptionBox getSampleDescriptionBox() { 131dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sampleDescriptionBox; 132dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 133dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 134dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public List<TimeToSampleBox.Entry> getDecodingTimeEntries() { 135dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return stts; 136dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 137dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 138dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public List<CompositionTimeToSample.Entry> getCompositionTimeEntries() { 139dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return ctts; 140dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 141dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 142dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long[] getSyncSamples() { 143dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long[] returns = new long[stss.size()]; 144dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < stss.size(); i++) { 145dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu returns[i] = stss.get(i); 146dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 147dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return returns; 148dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 149dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 150dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public List<SampleDependencyTypeBox.Entry> getSampleDependencies() { 151dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return sdtp; 152dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 153dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 154dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public TrackMetaData getTrackMetaData() { 155dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return trackMetaData; 156dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 157dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 158dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String getHandler() { 159dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return "vide"; 160dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 161dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 162dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public List<ByteBuffer> getSamples() { 163dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return samples; 164dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 165dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 166dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public AbstractMediaHeaderBox getMediaHeaderBox() { 167dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return new VideoMediaHeaderBox(); 168dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 169dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 170dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public SubSampleInformationBox getSubsampleInformationBox() { 171dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return null; 172dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 173dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 174dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean readVariables() { 175dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu width = (seqParameterSet.pic_width_in_mbs_minus1 + 1) * 16; 176dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int mult = 2; 177dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (seqParameterSet.frame_mbs_only_flag) { 178dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu mult = 1; 179dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 180dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu height = 16 * (seqParameterSet.pic_height_in_map_units_minus1 + 1) * mult; 181dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (seqParameterSet.frame_cropping_flag) { 182dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int chromaArrayType = 0; 183dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (seqParameterSet.residual_color_transform_flag == false) { 184dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu chromaArrayType = seqParameterSet.chroma_format_idc.getId(); 185dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 186dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int cropUnitX = 1; 187dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int cropUnitY = mult; 188dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (chromaArrayType != 0) { 189dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu cropUnitX = seqParameterSet.chroma_format_idc.getSubWidth(); 190dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu cropUnitY = seqParameterSet.chroma_format_idc.getSubHeight() * mult; 191dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 192dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 193dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu width -= cropUnitX * (seqParameterSet.frame_crop_left_offset + seqParameterSet.frame_crop_right_offset); 194dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu height -= cropUnitY * (seqParameterSet.frame_crop_top_offset + seqParameterSet.frame_crop_bottom_offset); 195dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 196dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return true; 197dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 198dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 199dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean findNextStartcode() throws IOException { 200dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byte[] test = new byte[]{-1, -1, -1, -1}; 201dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 202dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int c; 203dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu while ((c = reader.read()) != -1) { 204dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu test[0] = test[1]; 205dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu test[1] = test[2]; 206dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu test[2] = test[3]; 207dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu test[3] = (byte) c; 208dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (test[0] == 0 && test[1] == 0 && test[2] == 0 && test[3] == 1) { 209dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu prevScSize = currentScSize; 210dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu currentScSize = 4; 211dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return true; 212dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 213dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (test[0] == 0 && test[1] == 0 && test[2] == 1) { 214dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu prevScSize = currentScSize; 215dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu currentScSize = 3; 216dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return true; 217dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 218dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 219dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return false; 220dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 221dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 222dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private enum NALActions { 223dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IGNORE, BUFFER, STORE, END 224dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 225dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 226dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private boolean readSamples() throws IOException { 227dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (readSamples) { 228dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return true; 229dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 230dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 231dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu readSamples = true; 232dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 233dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 234dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu findNextStartcode(); 235dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu reader.mark(); 236dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long pos = reader.getPos(); 237dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 238dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ArrayList<byte[]> buffered = new ArrayList<byte[]>(); 239dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 240dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int frameNr = 0; 241dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 242dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu while (findNextStartcode()) { 243dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long newpos = reader.getPos(); 244dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int size = (int) (newpos - pos - prevScSize); 245dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu reader.reset(); 246dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byte[] data = new byte[size ]; 247dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu reader.read(data); 248dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int type = data[0]; 249dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int nal_ref_idc = (type >> 5) & 3; 250dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int nal_unit_type = type & 0x1f; 251dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LOG.fine("Found startcode at " + (pos -4) + " Type: " + nal_unit_type + " ref idc: " + nal_ref_idc + " (size " + size + ")"); 252dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu NALActions action = handleNALUnit(nal_ref_idc, nal_unit_type, data); 253dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu switch (action) { 254dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case IGNORE: 255dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 256dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 257dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case BUFFER: 258dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu buffered.add(data); 259dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 260dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 261dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case STORE: 262dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int stdpValue = 22; 263dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frameNr++; 264dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu buffered.add(data); 265dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteBuffer bb = createSample(buffered); 266dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu boolean IdrPicFlag = false; 267dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (nal_unit_type == 5) { 268dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu stdpValue += 16; 269dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu IdrPicFlag = true; 270dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 271dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteArrayInputStream bs = cleanBuffer(buffered.get(buffered.size() - 1)); 272dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu SliceHeader sh = new SliceHeader(bs, seqParameterSet, pictureParameterSet, IdrPicFlag); 273dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sh.slice_type == SliceHeader.SliceType.B) { 274dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu stdpValue += 4; 275dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 276dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LOG.fine("Adding sample with size " + bb.capacity() + " and header " + sh); 277dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu buffered.clear(); 278dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu samples.add(bb); 279dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu stts.add(new TimeToSampleBox.Entry(1, frametick)); 280dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (nal_unit_type == 5) { // IDR Picture 281dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu stss.add(frameNr); 282dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 283dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (seiMessage.n_frames == 0) { 284dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frameNrInGop = 0; 285dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 286dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int offset = 0; 287dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (seiMessage.clock_timestamp_flag) { 288dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu offset = seiMessage.n_frames - frameNrInGop; 289dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else if (seiMessage.removal_delay_flag) { 290dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu offset = seiMessage.dpb_removal_delay / 2; 291dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 292dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ctts.add(new CompositionTimeToSample.Entry(1, offset * frametick)); 293dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu sdtp.add(new SampleDependencyTypeBox.Entry(stdpValue)); 294dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frameNrInGop++; 295dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 296dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 297dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case END: 298dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return true; 299dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 300dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 301dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 302dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pos = newpos; 303dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu reader.seek(currentScSize); 304dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu reader.mark(); 305dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 306dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return true; 307dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 308dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 309dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private ByteBuffer createSample(List<byte[]> buffers) { 310dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int outsize = 0; 311dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < buffers.size(); i++) { 312dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu outsize += buffers.get(i).length + 4; 313dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 314dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byte[] output = new byte[outsize]; 315dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 316dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteBuffer bb = ByteBuffer.wrap(output); 317dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < buffers.size(); i++) { 318dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu bb.putInt(buffers.get(i).length); 319dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu bb.put(buffers.get(i)); 320dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 321dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu bb.rewind(); 322dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return bb; 323dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 324dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 325dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private ByteArrayInputStream cleanBuffer(byte[] data) { 326dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byte[] output = new byte[data.length]; 327dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int inPos = 0; 328dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int outPos = 0; 329dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu while (inPos < data.length) { 330dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (data[inPos] == 0 && data[inPos + 1] == 0 && data[inPos + 2] == 3) { 331dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu output[outPos] = 0; 332dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu output[outPos + 1] = 0; 333dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu inPos += 3; 334dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu outPos += 2; 335dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 336dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu output[outPos] = data[inPos]; 337dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu inPos++; 338dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu outPos++; 339dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 340dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 341dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return new ByteArrayInputStream(output, 0, outPos); 342dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 343dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 344dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private NALActions handleNALUnit(int nal_ref_idc, int nal_unit_type, byte[] data) throws IOException { 345dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu NALActions action; 346dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu switch (nal_unit_type) { 347dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 1: 348dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 2: 349dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 3: 350dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 4: 351dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 5: 352dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu action = NALActions.STORE; // Will only work in single slice per frame mode! 353dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 354dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 355dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 6: 356dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu seiMessage = new SEIMessage(cleanBuffer(data), seqParameterSet); 357dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu action = NALActions.BUFFER; 358dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 359dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 360dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 9: 361dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu// printAccessUnitDelimiter(data); 362dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int type = data[1] >> 5; 363dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LOG.fine("Access unit delimiter type: " + type); 364dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu action = NALActions.BUFFER; 365dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 366dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 367dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 368dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 7: 369dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (seqParameterSet == null) { 370dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteArrayInputStream is = cleanBuffer(data); 371dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu is.read(); 372dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu seqParameterSet = SeqParameterSet.read(is); 373dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu seqParameterSetList.add(data); 374dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu configureFramerate(); 375dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 376dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu action = NALActions.IGNORE; 377dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 378dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 379dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 8: 380dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (pictureParameterSet == null) { 381dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ByteArrayInputStream is = new ByteArrayInputStream(data); 382dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu is.read(); 383dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pictureParameterSet = PictureParameterSet.read(is); 384dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pictureParameterSetList.add(data); 385dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 386dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu action = NALActions.IGNORE; 387dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 388dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 389dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 10: 390dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 11: 391dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu action = NALActions.END; 392dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 393dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 394dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu default: 395dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu System.err.println("Unknown NAL unit type: " + nal_unit_type); 396dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu action = NALActions.IGNORE; 397dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 398dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 399dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 400dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return action; 401dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 402dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 403dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private void configureFramerate() { 404dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (determineFrameRate) { 405dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (seqParameterSet.vuiParams != null) { 406dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu timescale = seqParameterSet.vuiParams.time_scale >> 1; // Not sure why, but I found this in several places, and it works... 407dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frametick = seqParameterSet.vuiParams.num_units_in_tick; 408dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (timescale == 0 || frametick == 0) { 409dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu System.err.println("Warning: vuiParams contain invalid values: time_scale: " + timescale + " and frame_tick: " + frametick + ". Setting frame rate to 25fps"); 410dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu timescale = 90000; 411dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frametick = 3600; 412dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 413dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 414dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu System.err.println("Warning: Can't determine frame rate. Guessing 25 fps"); 415dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu timescale = 90000; 416dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frametick = 3600; 417dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 418dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 419dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 420dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 421dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void printAccessUnitDelimiter(byte[] data) { 422dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LOG.fine("Access unit delimiter: " + (data[1] >> 5)); 423dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 424dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 425dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public static class SliceHeader { 426dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 427dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public enum SliceType { 428dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu P, B, I, SP, SI 429dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 430dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 431dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int first_mb_in_slice; 432dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public SliceType slice_type; 433dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int pic_parameter_set_id; 434dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int colour_plane_id; 435dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int frame_num; 436dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean field_pic_flag = false; 437dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public boolean bottom_field_flag = false; 438dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int idr_pic_id; 439dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int pic_order_cnt_lsb; 440dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public int delta_pic_order_cnt_bottom; 441dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 442dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public SliceHeader(InputStream is, SeqParameterSet sps, PictureParameterSet pps, boolean IdrPicFlag) throws IOException { 443dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu is.read(); 444dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu CAVLCReader reader = new CAVLCReader(is); 445dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu first_mb_in_slice = reader.readUE("SliceHeader: first_mb_in_slice"); 446dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu switch (reader.readUE("SliceHeader: slice_type")) { 447dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 0: 448dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 5: 449dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu slice_type = SliceType.P; 450dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 451dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 452dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 1: 453dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 6: 454dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu slice_type = SliceType.B; 455dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 456dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 457dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 2: 458dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 7: 459dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu slice_type = SliceType.I; 460dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 461dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 462dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 3: 463dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 8: 464dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu slice_type = SliceType.SP; 465dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 466dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 467dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 4: 468dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 9: 469dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu slice_type = SliceType.SI; 470dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 471dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 472dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 473dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pic_parameter_set_id = reader.readUE("SliceHeader: pic_parameter_set_id"); 474dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.residual_color_transform_flag) { 475dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu colour_plane_id = reader.readU(2, "SliceHeader: colour_plane_id"); 476dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 477dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu frame_num = reader.readU(sps.log2_max_frame_num_minus4 + 4, "SliceHeader: frame_num"); 478dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 479dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (!sps.frame_mbs_only_flag) { 480dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu field_pic_flag = reader.readBool("SliceHeader: field_pic_flag"); 481dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (field_pic_flag) { 482dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu bottom_field_flag = reader.readBool("SliceHeader: bottom_field_flag"); 483dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 484dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 485dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (IdrPicFlag) { 486dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu idr_pic_id = reader.readUE("SliceHeader: idr_pic_id"); 487dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.pic_order_cnt_type == 0) { 488dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pic_order_cnt_lsb = reader.readU(sps.log2_max_pic_order_cnt_lsb_minus4 + 4, "SliceHeader: pic_order_cnt_lsb"); 489dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (pps.pic_order_present_flag && !field_pic_flag) { 490dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu delta_pic_order_cnt_bottom = reader.readSE("SliceHeader: delta_pic_order_cnt_bottom"); 491dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 492dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 493dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 494dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 495dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 496dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 497dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 498dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return "SliceHeader{" + 499dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu "first_mb_in_slice=" + first_mb_in_slice + 500dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", slice_type=" + slice_type + 501dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", pic_parameter_set_id=" + pic_parameter_set_id + 502dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", colour_plane_id=" + colour_plane_id + 503dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", frame_num=" + frame_num + 504dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", field_pic_flag=" + field_pic_flag + 505dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", bottom_field_flag=" + bottom_field_flag + 506dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", idr_pic_id=" + idr_pic_id + 507dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", pic_order_cnt_lsb=" + pic_order_cnt_lsb + 508dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", delta_pic_order_cnt_bottom=" + delta_pic_order_cnt_bottom + 509dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu '}'; 510dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 511dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 512dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 513dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private class ReaderWrapper { 514dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private InputStream inputStream; 515dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private long pos = 0; 516dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 517dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private long markPos = 0; 518dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 519dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 520dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu private ReaderWrapper(InputStream inputStream) { 521dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.inputStream = inputStream; 522dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 523dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 524dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int read() throws IOException { 525dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pos++; 526dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return inputStream.read(); 527dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 528dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 529dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long read(byte[] data) throws IOException { 530dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long read = inputStream.read(data); 531dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pos += read; 532dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return read; 533dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 534dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 535dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long seek(int dist) throws IOException { 536dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long seeked = inputStream.skip(dist); 537dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pos += seeked; 538dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return seeked; 539dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 540dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 541dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public long getPos() { 542dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return pos; 543dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 544dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 545dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void mark() { 546dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int i = 1048576; 547dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LOG.fine("Marking with " + i + " at " + pos); 548dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu inputStream.mark(i); 549dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu markPos = pos; 550dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 551dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 552dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 553dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public void reset() throws IOException { 554dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu long diff = pos - markPos; 555dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LOG.fine("Resetting to " + markPos + " (pos is " + pos + ") which makes the buffersize " + diff); 556dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu inputStream.reset(); 557dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pos = markPos; 558dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 559dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 560dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 561dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public class SEIMessage { 562dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 563dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int payloadType = 0; 564dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int payloadSize = 0; 565dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 566dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu boolean removal_delay_flag; 567dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int cpb_removal_delay; 568dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int dpb_removal_delay; 569dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 570dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu boolean clock_timestamp_flag; 571dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int pic_struct; 572dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int ct_type; 573dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int nuit_field_based_flag; 574dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int counting_type; 575dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int full_timestamp_flag; 576dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int discontinuity_flag; 577dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int cnt_dropped_flag; 578dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int n_frames; 579dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int seconds_value; 580dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int minutes_value; 581dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int hours_value; 582dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int time_offset_length; 583dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int time_offset; 584dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 585dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu SeqParameterSet sps; 586dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 587dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public SEIMessage(InputStream is, SeqParameterSet sps) throws IOException { 588dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu this.sps = sps; 589dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu is.read(); 590dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int datasize = is.available(); 591dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int read = 0; 592dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu while (read < datasize) { 593dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu payloadType = 0; 594dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu payloadSize = 0; 595dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int last_payload_type_bytes = is.read(); 596dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read++; 597dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu while (last_payload_type_bytes == 0xff) { 598dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu payloadType += last_payload_type_bytes; 599dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu last_payload_type_bytes = is.read(); 600dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read++; 601dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 602dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu payloadType += last_payload_type_bytes; 603dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int last_payload_size_bytes = is.read(); 604dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read++; 605dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 606dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu while (last_payload_size_bytes == 0xff) { 607dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu payloadSize += last_payload_size_bytes; 608dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu last_payload_size_bytes = is.read(); 609dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read++; 610dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 611dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu payloadSize += last_payload_size_bytes; 612dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (datasize - read >= payloadSize) { 613dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (payloadType == 1) { // pic_timing is what we are interested in! 614dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.vuiParams != null && (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null || sps.vuiParams.pic_struct_present_flag)) { 615dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu byte[] data = new byte[payloadSize]; 616dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu is.read(data); 617dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read += payloadSize; 618dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu CAVLCReader reader = new CAVLCReader(new ByteArrayInputStream(data)); 619dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null) { 620dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu removal_delay_flag = true; 621dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu cpb_removal_delay = reader.readU(sps.vuiParams.nalHRDParams.cpb_removal_delay_length_minus1 + 1, "SEI: cpb_removal_delay"); 622dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu dpb_removal_delay = reader.readU(sps.vuiParams.nalHRDParams.dpb_output_delay_length_minus1 + 1, "SEI: dpb_removal_delay"); 623dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 624dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu removal_delay_flag = false; 625dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 626dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.vuiParams.pic_struct_present_flag) { 627dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu pic_struct = reader.readU(4, "SEI: pic_struct"); 628dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu int numClockTS; 629dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu switch (pic_struct) { 630dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 0: 631dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 1: 632dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 2: 633dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu default: 634dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu numClockTS = 1; 635dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 636dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 637dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 3: 638dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 4: 639dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 7: 640dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu numClockTS = 2; 641dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 642dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 643dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 5: 644dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 6: 645dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu case 8: 646dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu numClockTS = 3; 647dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu break; 648dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 649dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < numClockTS; i++) { 650dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu clock_timestamp_flag = reader.readBool("pic_timing SEI: clock_timestamp_flag[" + i + "]"); 651dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (clock_timestamp_flag) { 652dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ct_type = reader.readU(2, "pic_timing SEI: ct_type"); 653dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu nuit_field_based_flag = reader.readU(1, "pic_timing SEI: nuit_field_based_flag"); 654dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu counting_type = reader.readU(5, "pic_timing SEI: counting_type"); 655dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu full_timestamp_flag = reader.readU(1, "pic_timing SEI: full_timestamp_flag"); 656dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu discontinuity_flag = reader.readU(1, "pic_timing SEI: discontinuity_flag"); 657dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu cnt_dropped_flag = reader.readU(1, "pic_timing SEI: cnt_dropped_flag"); 658dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu n_frames = reader.readU(8, "pic_timing SEI: n_frames"); 659dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (full_timestamp_flag == 1) { 660dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu seconds_value = reader.readU(6, "pic_timing SEI: seconds_value"); 661dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu minutes_value = reader.readU(6, "pic_timing SEI: minutes_value"); 662dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu hours_value = reader.readU(5, "pic_timing SEI: hours_value"); 663dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 664dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (reader.readBool("pic_timing SEI: seconds_flag")) { 665dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu seconds_value = reader.readU(6, "pic_timing SEI: seconds_value"); 666dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (reader.readBool("pic_timing SEI: minutes_flag")) { 667dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu minutes_value = reader.readU(6, "pic_timing SEI: minutes_value"); 668dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (reader.readBool("pic_timing SEI: hours_flag")) { 669dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu hours_value = reader.readU(5, "pic_timing SEI: hours_value"); 670dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 671dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 672dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 673dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 674dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (true) { 675dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.vuiParams.nalHRDParams != null) { 676dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu time_offset_length = sps.vuiParams.nalHRDParams.time_offset_length; 677dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else if (sps.vuiParams.vclHRDParams != null) { 678dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu time_offset_length = sps.vuiParams.vclHRDParams.time_offset_length; 679dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 680dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu time_offset_length = 24; 681dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 682dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu time_offset = reader.readU(24, "pic_timing SEI: time_offset"); 683dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 684dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 685dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 686dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 687dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 688dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 689dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < payloadSize; i++) { 690dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu is.read(); 691dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read++; 692dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 693dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 694dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 695dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu for (int i = 0; i < payloadSize; i++) { 696dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu is.read(); 697dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read++; 698dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 699dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 700dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } else { 701dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu read = datasize; 702dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 703dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu LOG.fine(this.toString()); 704dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 705dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 706dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 707dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu @Override 708dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu public String toString() { 709dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu String out = "SEIMessage{" + 710dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu "payloadType=" + payloadType + 711dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", payloadSize=" + payloadSize; 712dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (payloadType == 1) { 713dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.vuiParams.nalHRDParams != null || sps.vuiParams.vclHRDParams != null) { 714dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu 715dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu out += ", cpb_removal_delay=" + cpb_removal_delay + 716dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", dpb_removal_delay=" + dpb_removal_delay; 717dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 718dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (sps.vuiParams.pic_struct_present_flag) { 719dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu out += ", pic_struct=" + pic_struct; 720dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu if (clock_timestamp_flag) { 721dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu out += ", ct_type=" + ct_type + 722dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", nuit_field_based_flag=" + nuit_field_based_flag + 723dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", counting_type=" + counting_type + 724dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", full_timestamp_flag=" + full_timestamp_flag + 725dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", discontinuity_flag=" + discontinuity_flag + 726dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", cnt_dropped_flag=" + cnt_dropped_flag + 727dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", n_frames=" + n_frames + 728dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", seconds_value=" + seconds_value + 729dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", minutes_value=" + minutes_value + 730dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", hours_value=" + hours_value + 731dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", time_offset_length=" + time_offset_length + 732dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu ", time_offset=" + time_offset; 733dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 734dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 735dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 736dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu out += '}'; 737dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu return out; 738dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 739dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu } 740dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu} 741