public VideoTrack(IBox trak, MP4InputStream inStream) : base(trak, inStream) { throw new NotImplementedException(); // Box minf = trak.getChild(BoxType.MEDIA_BOX).getChild(BoxType.MEDIA_INFORMATION_BOX); // vmhd = (VideoMediaHeaderBox) minf.getChild(BoxType.VIDEO_MEDIA_HEADER_BOX); // Box stbl = minf.getChild(BoxType.SAMPLE_TABLE_BOX); // //sample descriptions: 'mp4v' has an ESDBox, all others have a CodecSpecificBox // SampleDescriptionBox stsd = (SampleDescriptionBox) stbl.getChild(BoxType.SAMPLE_DESCRIPTION_BOX); // if(stsd.getChildren().get(0) instanceof VideoSampleEntry) { // sampleEntry = (VideoSampleEntry) stsd.getChildren().get(0); // long type = sampleEntry.getType(); // if(type==BoxType.MP4V_SAMPLE_ENTRY) findDecoderSpecificInfo((ESDBox) sampleEntry.getChild(BoxType.ESD_BOX)); // else if(type==BoxType.ENCRYPTED_VIDEO_SAMPLE_ENTRY||type==BoxType.DRMS_SAMPLE_ENTRY) { // findDecoderSpecificInfo((ESDBox) sampleEntry.getChild(BoxType.ESD_BOX)); // protection = Protection.parse(sampleEntry.getChild(BoxType.PROTECTION_SCHEME_INFORMATION_BOX)); // } // else decoderInfo = DecoderInfo.parse((CodecSpecificBox) sampleEntry.getChildren().get(0)); // codec = VideoCodec.forType(sampleEntry.getType()); // } // else { // sampleEntry = null; // codec = VideoCodec.UNKNOWN_VIDEO_CODEC; // } }
// --- children --- protected void readChildren(MP4InputStream inStream) { while ((size - (inStream.getOffset() - start)) > 0) { Descriptor desc = createDescriptor(inStream); children.Add(desc); } }
public void readChildren(MP4InputStream inStream) { while (inStream.getOffset() < (offset + size)) { var box = BoxFactory.parseBox(this, inStream); children.Add(box); } }
public void readChildren(MP4InputStream inStream, int len) { for (int i = 0; i < len; i++) { var box = BoxFactory.parseBox(this, inStream); children.Add(box); } }
public override void decode(MP4InputStream inStream) { base.decode(inStream); while (getLeft(inStream) > 0) { int rate = (int)inStream.readBytes(4); int initialDelay = (int)inStream.readBytes(4); pairs.Add(new KeyValuePair <int, int>(rate, initialDelay)); } }
public override void decode(MP4InputStream inStream) { base.decode(inStream); referenceType = inStream.readString(4); while (getLeft(inStream) > 3) { trackIDs.Add((int)inStream.readBytes(4)); } }
public override void decode(MP4InputStream inStream) { base.decode(inStream); dataType = forInt(flags); inStream.skipBytes(4); // padding? data = new byte[(int)getLeft(inStream)]; inStream.read(data, 0, data.Length); }
public override void decode(MP4InputStream inStream) { base.decode(inStream); try { string tmp = inStream.readString((int)getLeft(inStream)); } catch { inStream.skipBytes(getLeft(inStream)); } }
public override void decode(MP4InputStream inStream) { base.decode(inStream); graphicsMode = inStream.readBytes(2); // 6 byte RGB color var c = new int[3]; for (int i = 0; i < 3; i++) { c[i] = (inStream.read() & 0xFF) | ((inStream.read() << 8) & 0xFF); } color = Color.FromArgb(c[0], c[1], c[2]); }
public override void decode(MP4InputStream inStream) { base.decode(inStream); inStream.skipBytes(4); //pre-defined: 0 handlerType = inStream.readBytes(4); inStream.readBytes(4); //reserved inStream.readBytes(4); //reserved inStream.readBytes(4); //reserved handlerName = inStream.readEncodedString((int)getLeft(inStream), Encoding.UTF8); }
public override void decode(MP4InputStream inStream) { // 3gpp or iTunes if (parent.getType() == BoxType.USER_DATA_BOX) { base.decode(inStream); languageCode = BoxUtils.getLanguageCode(inStream.readBytes(2)); var b = inStream.readTerminated((int)getLeft(inStream), 0); genre = Encoding.UTF8.GetString(b); } else { readChildren(inStream); } }
public AudioTrack(IBox trak, MP4InputStream inStream) : base(trak, inStream) { var mdia = trak.getChild(BoxType.MEDIA_BOX); var minf = mdia.getChild(BoxType.MEDIA_INFORMATION_BOX); smhd = (SoundMediaHeaderBox)minf.getChild(BoxType.SOUND_MEDIA_HEADER_BOX); var stbl = minf.getChild(BoxType.SAMPLE_TABLE_BOX); // sample descriptions: 'mp4a' and 'enca' have an ESDBox, all others have a CodecSpecificBox var stsd = (SampleDescriptionBox)stbl.getChild(BoxType.SAMPLE_DESCRIPTION_BOX); sampleEntry = stsd.getChildren()[0] as AudioSampleEntry; if (sampleEntry != null) { var type = sampleEntry.getType(); if (sampleEntry.hasChild(BoxType.ESD_BOX)) { findDecoderSpecificInfo((ESDBox)sampleEntry.getChild(BoxType.ESD_BOX)); } else { throw new NotImplementedException(); // decoderInfo = DecoderInfo.parse((CodecSpecificBox)sampleEntry.getChildren()[0]); } if (type == BoxType.ENCRYPTED_AUDIO_SAMPLE_ENTRY || type == BoxType.DRMS_SAMPLE_ENTRY) { findDecoderSpecificInfo((ESDBox)sampleEntry.getChild(BoxType.ESD_BOX)); protection = Protection.parse(sampleEntry.getChild(BoxType.PROTECTION_SCHEME_INFORMATION_BOX)); codec = protection.getOriginalFormat(); } else { codec = AudioCodec.forType(sampleEntry.getType()); } } else { codec = new AudioCodec(AudioCodec.CodecType.UNKNOWN_AUDIO_CODEC); } }
public override void decode(MP4InputStream inStream) { // 3gpp or iTunes if (parent.getType() == BoxType.USER_DATA_BOX) { base.decode(inStream); // TODO: what to do with both? long entity = inStream.readBytes(4); long criteria = inStream.readBytes(4); languageCode = BoxUtils.getLanguageCode(inStream.readBytes(2)); var b = inStream.readTerminated((int)getLeft(inStream), 0); rating = Encoding.UTF8.GetString(b); } else { readChildren(inStream); } }
public Movie(IBox moov, MP4InputStream inStream) { this.inStream = inStream; // --- create tracks --- mvhd = (MovieHeaderBox)moov.getChild(BoxType.MOVIE_HEADER_BOX); foreach (var trackBox in moov.getChildren(BoxType.TRACK_BOX)) { var track = createTrack(trackBox); if (track != null) { tracks.Add(track); } } // --- read metadata: moov.meta/moov.udta.meta --- metaData = new MetaData(); if (moov.hasChild(BoxType.META_BOX)) { metaData.parse(null, moov.getChild(BoxType.META_BOX)); } else if (moov.hasChild(BoxType.USER_DATA_BOX)) { var udta = moov.getChild(BoxType.USER_DATA_BOX); if (udta.hasChild(BoxType.META_BOX)) { metaData.parse(udta, udta.getChild(BoxType.META_BOX)); } } // --- detect DRM --- protections = new List <Protection>(); if (moov.hasChild(BoxType.ITEM_PROTECTION_BOX)) { var ipro = moov.getChild(BoxType.ITEM_PROTECTION_BOX); foreach (var sinf in ipro.getChildren(BoxType.PROTECTION_SCHEME_INFORMATION_BOX)) { protections.Add(Protection.parse(sinf)); } } }
protected Track(IBox trak, MP4InputStream inStream) { this.inStream = inStream; tkhd = (TrackHeaderBox)trak.getChild(BoxType.TRACK_HEADER_BOX); var mdia = trak.getChild(BoxType.MEDIA_BOX); mdhd = (MediaHeaderBox)mdia.getChild(BoxType.MEDIA_HEADER_BOX); var minf = mdia.getChild(BoxType.MEDIA_INFORMATION_BOX); var dinf = minf.getChild(BoxType.DATA_INFORMATION_BOX); var dref = (DataReferenceBox)dinf.getChild(BoxType.DATA_REFERENCE_BOX); // --- sample table --- var stbl = minf.getChild(BoxType.SAMPLE_TABLE_BOX); if (stbl.hasChildren()) { parseSampleTable(stbl); } }
public static Descriptor createDescriptor(MP4InputStream inStream) { //read tag and size int type = inStream.read(); int read = 1; int size = 0; int b = 0; do { b = inStream.read(); size <<= 7; size |= b & 0x7f; read++; }while ((b & 0x80) == 0x80); //create descriptor Descriptor desc = forTag(type); desc.type = type; desc.size = size; desc.start = inStream.getOffset(); //decode desc.decode(inStream); //skip remaining bytes long remaining = size - (inStream.getOffset() - desc.start); if (remaining > 0) { Logger.LogBoxes(string.Format("Descriptor: bytes left: {0:N0}, offset: {1:N0}", remaining, inStream.getOffset())); inStream.skipBytes(remaining); } desc.size += read; //include type and size fields return(desc); }
/// <summary> /// Decodes the given input stream by reading this box and all of its children (if any). /// </summary> /// <param name="inStream">an input stream</param> public virtual void decode(MP4InputStream inStream) { }
protected long getLeft(MP4InputStream inStream) { return((offset + size) - inStream.getOffset()); }
public static IBox parseBox(IBox parent, MP4InputStream inStream) { long offset = inStream.getOffset(); long size = inStream.readBytes(4); var type = (BoxType)(uint)inStream.readBytes(4); if (size == 1) { size = inStream.readBytes(8); } if (type == BoxType.EXTENDED_TYPE) { inStream.skipBytes(16); } if (type == 0) { return(new UnknownBox()); } // --- error protection --- if (parent != null) { long parentLeft = (parent.getOffset() + parent.getSize()) - offset; if (size > parentLeft) { throw new Exception("error while decoding box '" + type + "' ('" + typeToString(type) + "') at offset " + offset.ToString("N0") + ": box too large for parent"); } } Logger.LogBoxes("[" + offset.ToString("N0") + "] " + GetBoxPath(type, parent)); var box = forType(type, inStream.getOffset()); box.setParams(parent, size, type, offset); box.decode(inStream); // --- if box doesn't contain data it only contains children --- if (box.GetType() == typeof(BoxImpl) || box.GetType() == typeof(FullBox)) { box.readChildren(inStream); } // --- check bytes left --- long left = (box.getOffset() + box.getSize()) - inStream.getOffset(); if (left > 0) { if (!(box is MediaDataBox) && !(box is UnknownBox) && !(box is FreeSpaceBox)) { Logger.LogInfo(string.Format("bytes left after reading box {0}: left: {1}, offset: {2}", typeToString(type), left, inStream.getOffset())); } // --- skip left Data --- inStream.skipBytes(left); } else if (left < 0) { Logger.LogServe(string.Format("box {0} overread: {1} bytes, offset: {2}", typeToString(type), -left, inStream.getOffset())); } return(box); }
public abstract void decode(MP4InputStream inStream);
public MP4Container(Stream inStream) { this.inStream = new MP4InputStream(inStream); readContent(); }