List of usage examples for java.util LinkedList remove
public E remove()
From source file:org.red5.io.mp4.impl.MP4Reader.java
/** * This handles the moov atom being at the beginning or end of the file, so the mdat may also be before or after the moov atom. */// w ww. ja v a 2s. c om public void decodeHeader() { try { // we want a moov and an mdat, anything else will throw the invalid file type error MovieBox moov = isoFile.getBoxes(MovieBox.class).get(0); if (log.isDebugEnabled()) { log.debug("moov children: {}", moov.getBoxes().size()); dumpBox(moov); } // get the movie header MovieHeaderBox mvhd = moov.getMovieHeaderBox(); // get the timescale and duration timeScale = mvhd.getTimescale(); duration = mvhd.getDuration(); log.debug("Time scale {} Duration {}", timeScale, duration); double lengthInSeconds = (double) duration / timeScale; log.debug("Seconds {}", lengthInSeconds); // look at the tracks log.debug("Tracks: {}", moov.getTrackCount()); List<TrackBox> tracks = moov.getBoxes(TrackBox.class); // trak for (TrackBox trak : tracks) { if (log.isDebugEnabled()) { log.debug("trak children: {}", trak.getBoxes().size()); dumpBox(trak); } TrackHeaderBox tkhd = trak.getTrackHeaderBox(); // tkhd log.debug("Track id: {}", tkhd.getTrackId()); if (tkhd != null && tkhd.getWidth() > 0) { width = (int) tkhd.getWidth(); height = (int) tkhd.getHeight(); log.debug("Width {} x Height {}", width, height); } MediaBox mdia = trak.getMediaBox(); // mdia long scale = 0; boolean isAudio = false, isVideo = false; if (mdia != null) { if (log.isDebugEnabled()) { log.debug("mdia children: {}", mdia.getBoxes().size()); dumpBox(mdia); } MediaHeaderBox mdhd = mdia.getMediaHeaderBox(); // mdhd if (mdhd != null) { log.debug("Media data header atom found"); // this will be for either video or audio depending media info scale = mdhd.getTimescale(); log.debug("Time scale {}", scale); } HandlerBox hdlr = mdia.getHandlerBox(); // hdlr if (hdlr != null) { String hdlrType = hdlr.getHandlerType(); if ("vide".equals(hdlrType)) { hasVideo = true; if (scale > 0) { videoTimeScale = scale * 1.0; log.debug("Video time scale: {}", videoTimeScale); } } else if ("soun".equals(hdlrType)) { hasAudio = true; if (scale > 0) { audioTimeScale = scale * 1.0; log.debug("Audio time scale: {}", audioTimeScale); } } else { log.debug("Unhandled handler type: {}", hdlrType); } } MediaInformationBox minf = mdia.getMediaInformationBox(); if (minf != null) { if (log.isDebugEnabled()) { log.debug("minf children: {}", minf.getBoxes().size()); dumpBox(minf); } AbstractMediaHeaderBox abs = minf.getMediaHeaderBox(); if (abs != null) { if (abs instanceof SoundMediaHeaderBox) { // smhd //SoundMediaHeaderBox smhd = (SoundMediaHeaderBox) abs; log.debug("Sound header atom found"); isAudio = true; } else if (abs instanceof VideoMediaHeaderBox) { // vmhd //VideoMediaHeaderBox vmhd = (VideoMediaHeaderBox) abs; log.debug("Video header atom found"); isVideo = true; } else { log.debug("Unhandled media header box: {}", abs.getType()); } } else { log.debug("Null media header box"); } } } SampleTableBox stbl = trak.getSampleTableBox(); // mdia/minf/stbl if (stbl != null) { if (log.isDebugEnabled()) { log.debug("stbl children: {}", stbl.getBoxes().size()); dumpBox(stbl); } SampleDescriptionBox stsd = stbl.getSampleDescriptionBox(); // stsd if (stsd != null) { //stsd: mp4a, avc1, mp4v //String type = stsd.getType(); if (log.isDebugEnabled()) { log.debug("stsd children: {}", stsd.getBoxes().size()); dumpBox(stsd); } SampleEntry entry = stsd.getSampleEntry(); if (entry != null) { log.debug("Sample entry type: {}", entry.getType()); // determine if audio or video and process from there if (entry instanceof AudioSampleEntry) { processAudioBox(stbl, (AudioSampleEntry) entry, scale); } else if (entry instanceof VisualSampleEntry) { processVideoBox(stbl, (VisualSampleEntry) entry, scale); } } else { log.debug("Sample entry was null"); if (isVideo) { processVideoBox(stbl, scale); } else if (isAudio) { processAudioBox(stbl, scale); } } } } } //calculate FPS fps = (videoSampleCount * timeScale) / (double) duration; log.debug("FPS calc: ({} * {}) / {}", new Object[] { videoSampleCount, timeScale, duration }); log.debug("FPS: {}", fps); //real duration StringBuilder sb = new StringBuilder(); double videoTime = ((double) duration / (double) timeScale); log.debug("Video time: {}", videoTime); int minutes = (int) (videoTime / 60); if (minutes > 0) { sb.append(minutes); sb.append('.'); } //formatter for seconds / millis NumberFormat df = DecimalFormat.getInstance(); df.setMaximumFractionDigits(2); sb.append(df.format((videoTime % 60))); formattedDuration = sb.toString(); log.debug("Time: {}", formattedDuration); List<MediaDataBox> mdats = isoFile.getBoxes(MediaDataBox.class); if (mdats != null && !mdats.isEmpty()) { log.debug("mdat count: {}", mdats.size()); MediaDataBox mdat = mdats.get(0); if (mdat != null) { mdatOffset = mdat.getOffset(); } } //log.debug("Offsets - moov: {} mdat: {}", moovOffset, mdatOffset); log.debug("Offset - mdat: {}", mdatOffset); // handle fragmentation boolean fragmented = false; // detect whether or not this movie contains fragments first List<MovieFragmentBox> moofs = isoFile.getBoxes(MovieFragmentBox.class); // moof if (moofs != null && !moofs.isEmpty()) { log.info("Movie contains {} framents", moofs.size()); fragmented = true; for (MovieFragmentBox moof : moofs) { dumpBox(moof); MovieFragmentHeaderBox mfhd = moof.getBoxes(MovieFragmentHeaderBox.class).get(0); if (mfhd != null) { log.debug("Sequence: {} path: {}", mfhd.getSequenceNumber(), mfhd.getPath()); } List<TrackFragmentBox> trafs = moof.getBoxes(TrackFragmentBox.class); for (TrackFragmentBox traf : trafs) { TrackFragmentHeaderBox tfhd = traf.getTrackFragmentHeaderBox(); log.debug("tfhd: {}", tfhd); } List<TrackExtendsBox> trexs = moof.getBoxes(TrackExtendsBox.class); for (TrackExtendsBox trex : trexs) { log.debug("trex - track id: {} duration: {} sample size: {}", trex.getTrackId(), trex.getDefaultSampleDuration(), trex.getDefaultSampleSize()); } //List<Long> syncSamples = moof.getSyncSamples(sdtp); if (compositionTimes == null) { compositionTimes = new ArrayList<CompositionTimeToSample.Entry>(); } LinkedList<Integer> dataOffsets = new LinkedList<Integer>(); LinkedList<Long> sampleSizes = new LinkedList<Long>(); List<TrackRunBox> truns = moof.getTrackRunBoxes(); log.info("Fragment contains {} TrackRunBox entries", truns.size()); for (TrackRunBox trun : truns) { log.debug("trun - {}", trun); //videoSamplesToChunks if (trun.isDataOffsetPresent()) { dataOffsets.add(trun.getDataOffset()); } videoSampleCount += trun.getSampleCount(); List<TrackRunBox.Entry> recs = trun.getEntries(); log.info("TrackRunBox contains {} entries", recs.size()); for (TrackRunBox.Entry rec : recs) { log.info("Entry: {}", rec); if (trun.isSampleCompositionTimeOffsetPresent()) { CompositionTimeToSample.Entry ctts = new CompositionTimeToSample.Entry( (int) trun.getSampleCount(), (int) rec.getSampleCompositionTimeOffset()); compositionTimes.add(ctts); } sampleSizes.add(rec.getSampleSize()); if (trun.isSampleDurationPresent()) { videoSampleDuration += rec.getSampleDuration(); } } } // SampleToChunkBox.Entry log.info("Video duration: {}", videoSampleDuration); videoSamples = new long[sampleSizes.size()]; for (int i = 0; i < videoSamples.length; i++) { videoSamples[i] = sampleSizes.remove(); } log.info("Video samples: {}", Arrays.toString(videoSamples)); videoChunkOffsets = new long[dataOffsets.size()]; for (int i = 0; i < videoChunkOffsets.length; i++) { videoChunkOffsets[i] = dataOffsets.remove(); } log.info("Video chunk offsets: {}", Arrays.toString(videoChunkOffsets)); } } if (isoFile.getBoxes(MovieFragmentRandomAccessBox.class).size() > 0) { // mfra log.info("Movie contains frament random access info"); } if (isoFile.getBoxes(ActionMessageFormat0SampleEntryBox.class).size() > 0) { log.info("Movie contains AMF entries"); } // if we have fragments, we should have an mvex if (fragmented) { MovieExtendsBox mvex = moov.getBoxes(MovieExtendsBox.class).get(0); // mvex dumpBox(mvex); List<TrackExtendsBox> trexs = mvex.getBoxes(TrackExtendsBox.class); for (TrackExtendsBox trex : trexs) { log.debug("trex - track id: {} duration: {} sample size: {}", trex.getTrackId(), trex.getDefaultSampleDuration(), trex.getDefaultSampleSize()); } } } catch (Exception e) { log.error("Exception decoding header / atoms", e); } }