示例#1
0
        /// <summary>
        /// Loads MediaHeader atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_media_header_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
            if (version == 1)
            {
                creationTime     = createDate(bitstream.ReadBytes(8));
                modificationTime = createDate(bitstream.ReadBytes(8));
                timeScale        = (int)bitstream.ReadBytes(4);
                duration         = bitstream.ReadBytes(8);
                _bytesRead      += 28;
            }
            else
            {
                creationTime     = createDate(bitstream.ReadBytes(4));
                modificationTime = createDate(bitstream.ReadBytes(4));
                timeScale        = (int)bitstream.ReadBytes(4);
                duration         = bitstream.ReadBytes(4);
                _bytesRead      += 16;
            }
            int packedLanguage = (int)bitstream.ReadBytes(2);
            int qt_quality     = (int)bitstream.ReadBytes(2);

            _bytesRead += 4;
            return(_bytesRead);
        }
示例#2
0
 /// <summary>
 /// Loads M4ESDAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_esd_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     esd_descriptor = Mp4Descriptor.CreateDescriptor(bitstream);
     _bytesRead    += esd_descriptor.BytesRead;
     return(_bytesRead);
 }
示例#3
0
        /// <summary>
        /// Loads AudioSampleEntry atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_audio_sample_entry_atom(Mp4DataStream bitstream)
        {
            //qtff page 117
#if !SILVERLIGHT
            log.Debug("Audio sample entry");
#endif
            bitstream.SkipBytes(6);
            int dataReferenceIndex = (int)bitstream.ReadBytes(2);
            bitstream.SkipBytes(8);
            channelCount = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Channels: {0}", channelCount));
#endif
            sampleSize = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Sample size (bits): {0}", sampleSize));
#endif
            bitstream.SkipBytes(4);
            timeScale = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Time scale: {0}", timeScale));
#endif
            bitstream.SkipBytes(2);
            _bytesRead += 28;
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return(_bytesRead);
        }
示例#4
0
 public static Mp4Descriptor CreateDescriptor(Mp4DataStream bitstream)
 {
     int tag = (int)bitstream.ReadBytes(1);
     int bytesRead = 1;
     int size = 0;
     int b = 0;
     do
     {
         b = (int)bitstream.ReadBytes(1);
         size <<= 7;
         size |= b & 0x7f;
         bytesRead++;
     } while ((b & 0x80) == 0x80);
     Mp4Descriptor descriptor = new Mp4Descriptor(tag, size);
     switch (tag)
     {
         case MP4ES_DescriptorTag:
             descriptor.CreateESDescriptor(bitstream);
             break;
         case MP4DecoderConfigDescriptorTag:
             descriptor.CreateDecoderConfigDescriptor(bitstream);
             break;
         case MP4DecSpecificInfoDescriptorTag:
             descriptor.CreateDecSpecificInfoDescriptor(bitstream);
             break;
         default:
             break;
     }
     bitstream.SkipBytes(descriptor._size - descriptor._bytesRead);
     descriptor._bytesRead = bytesRead + descriptor._size;
     return descriptor;
 }
示例#5
0
        /// <summary>
        /// Loads the MP4ES_Descriptor from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        public void CreateESDescriptor(Mp4DataStream bitstream)
        {
            int  ES_ID = (int)bitstream.ReadBytes(2);
            int  flags = (int)bitstream.ReadBytes(1);
            bool streamDependenceFlag = (flags & (1 << 7)) != 0;
            bool urlFlag = (flags & (1 << 6)) != 0;
            bool ocrFlag = (flags & (1 << 5)) != 0;

            _bytesRead += 3;
            if (streamDependenceFlag)
            {
                bitstream.SkipBytes(2);
                _bytesRead += 2;
            }
            if (urlFlag)
            {
                int str_size = (int)bitstream.ReadBytes(1);
                bitstream.ReadString(str_size);
                _bytesRead += str_size + 1;
            }
            if (ocrFlag)
            {
                bitstream.SkipBytes(2);
                _bytesRead += 2;
            }
            while (_bytesRead < _size)
            {
                Mp4Descriptor descriptor = CreateDescriptor(bitstream);
                _children.Add(descriptor);
                _bytesRead += descriptor.BytesRead;
            }
        }
示例#6
0
 /// <summary>
 /// Loads MP4SoundMediaHeaderAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_sound_media_header_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     balance = (int)bitstream.ReadBytes(2);
     bitstream.SkipBytes(2);
     _bytesRead += 4;
     return(_bytesRead);
 }
示例#7
0
        /// <summary>
        /// Loads the version of the full atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_full_atom(Mp4DataStream bitstream)
        {
            long value = bitstream.ReadBytes(4);

            version     = (int)value >> 24;
            flags       = (int)value & 0xffffff;
            _bytesRead += 4;
            return(_bytesRead);
        }
示例#8
0
 /// <summary>
 /// Loads the composite atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_composite_atom(Mp4DataStream bitstream)
 {
     while (_bytesRead < _size)
     {
         Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
         _children.Add(child);
         _bytesRead += child.Size;
     }
     return(_bytesRead);
 }
示例#9
0
 public void CreateDecSpecificInfoDescriptor(Mp4DataStream bitstream)
 {
     decSpecificDataOffset = bitstream.Offset;
     dsid = new byte[_size];
     for (int b = 0; b < _size; b++)
     {
         dsid[b] = (byte)bitstream.ReadBytes(1);
         _bytesRead++;
     }
     decSpecificDataSize = _size - _bytesRead;
 }
示例#10
0
        /// <summary>
        /// Loads MP4VideoSampleEntryAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_video_sample_entry_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Video entry atom contains wxh");
#endif
            bitstream.SkipBytes(6);
            int dataReferenceIndex = (int)bitstream.ReadBytes(2);
            bitstream.SkipBytes(2);
            bitstream.SkipBytes(2);
            bitstream.SkipBytes(12);
            width = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Width: {0}", width));
#endif
            height = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Height: {0}", height));
#endif
            int horizontalRez = (int)bitstream.ReadBytes(4) >> 16;
#if !SILVERLIGHT
            log.Debug(string.Format("H Resolution: {0}", horizontalRez));
#endif
            int verticalRez = (int)bitstream.ReadBytes(4) >> 16;
#if !SILVERLIGHT
            log.Debug(string.Format("V Resolution: {0}", verticalRez));
#endif
            bitstream.SkipBytes(4);
            int frameCount = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Frame to sample count: {0}", frameCount));
#endif
            int stringLen = (int)bitstream.ReadBytes(1);
#if !SILVERLIGHT
            log.Debug(string.Format("String length (cpname): {0}", stringLen));
#endif
            String compressorName = bitstream.ReadString(31);
#if !SILVERLIGHT
            log.Debug(string.Format("Compressor name: {0}", compressorName.Trim()));
#endif
            int depth = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Depth: {0}", depth));
#endif
            bitstream.SkipBytes(2);
            _bytesRead += 78;
#if !SILVERLIGHT
            log.Debug(string.Format("Bytes read: {0}", _bytesRead));
#endif
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return(_bytesRead);
        }
示例#11
0
        /// <summary>
        /// Loads AVCC atom from the input bitstream.
        /// <para>
        /// 8+ bytes ISO/IEC 14496-10 or 3GPP AVC decode config box
        ///  = long unsigned offset + long ASCII text string 'avcC'
        /// -> 1 byte version = 8-bit hex version  (current = 1)
        /// -> 1 byte H.264 profile = 8-bit unsigned stream profile
        /// -> 1 byte H.264 compatible profiles = 8-bit hex flags
        /// -> 1 byte H.264 level = 8-bit unsigned stream level
        /// -> 1 1/2 nibble reserved = 6-bit unsigned value set to 63
        /// -> 1/2 nibble NAL length = 2-bit length byte size type
        ///  - 1 byte = 0 ; 2 bytes = 1 ; 4 bytes = 3
        /// -> 1 byte number of SPS = 8-bit unsigned total
        /// -> 2+ bytes SPS length = short unsigned length
        /// -> + SPS NAL unit = hexdump
        /// -> 1 byte number of PPS = 8-bit unsigned total
        /// -> 2+ bytes PPS length = short unsigned length
        /// -> + PPS NAL unit = hexdump
        /// </para>
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_avc_config_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("AVC config");
            log.Debug(string.Format("Offset: {0}", bitstream.Offset));
#endif
            //store the decoder config bytes
            videoConfigBytes = new byte[(int)_size];
            for (int b = 0; b < videoConfigBytes.Length; b++)
            {
                videoConfigBytes[b] = (byte)bitstream.ReadBytes(1);
                switch (b)
                {
                //0 / version
                case 1:     //profile
                    avcProfile = videoConfigBytes[b];
#if !SILVERLIGHT
                    log.Debug(string.Format("AVC profile: {0}", avcProfile));
#endif
                    break;

                case 2:     //compatible profile
                    int avcCompatProfile = videoConfigBytes[b];
#if !SILVERLIGHT
                    log.Debug(string.Format("AVC compatible profile: {0}", avcCompatProfile));
#endif
                    break;

                case 3:     //avc level
                    avcLevel = videoConfigBytes[b];
#if !SILVERLIGHT
                    log.Debug(string.Format("AVC level: {0}", avcLevel));
#endif
                    break;

                case 4:     //NAL length
                    break;

                case 5:     //SPS number
                    int numberSPS = videoConfigBytes[b];
#if !SILVERLIGHT
                    log.Debug(string.Format("Number of SPS: {0}", numberSPS));
#endif
                    break;

                default:
                    break;
                }
                _bytesRead++;
            }
            return(_bytesRead);
        }
示例#12
0
 /// <summary>
 /// Loads ChunkOffset atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_chunk_offset_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     entryCount  = (int)bitstream.ReadBytes(4);
     _bytesRead += 4;
     for (int i = 0; i < entryCount; i++)
     {
         long chunkOffset = bitstream.ReadBytes(4);
         chunks.Add(chunkOffset);
         _bytesRead += 4;
     }
     return(_bytesRead);
 }
示例#13
0
 /// <summary>
 /// Loads MP4VideoMediaHeaderAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_video_media_header_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     if ((_size - _bytesRead) == 8)
     {
         graphicsMode = (int)bitstream.ReadBytes(2);
         opColorRed   = (int)bitstream.ReadBytes(2);
         opColorGreen = (int)bitstream.ReadBytes(2);
         opColorBlue  = (int)bitstream.ReadBytes(2);
         _bytesRead  += 8;
     }
     return(_bytesRead);
 }
示例#14
0
 /// <summary>
 /// Loads MP4SampleToChunkAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_sample_to_chunk_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     entryCount  = (int)bitstream.ReadBytes(4);
     _bytesRead += 4;
     for (int i = 0; i < entryCount; i++)
     {
         int firstChunk             = (int)bitstream.ReadBytes(4);
         int samplesPerChunk        = (int)bitstream.ReadBytes(4);
         int sampleDescriptionIndex = (int)bitstream.ReadBytes(4);
         records.Add(new Record(firstChunk, samplesPerChunk, sampleDescriptionIndex));
         _bytesRead += 12;
     }
     return(_bytesRead);
 }
示例#15
0
        /// <summary>
        /// Loads MP4TrackHeaderAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_track_header_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
#if !SILVERLIGHT
            log.Debug(string.Format("Version: {0}", version));
#endif
            if (version == 1)
            {
                creationTime     = createDate(bitstream.ReadBytes(8));
                modificationTime = createDate(bitstream.ReadBytes(8));
                trackId          = bitstream.ReadBytes(4);
                bitstream.SkipBytes(4);
                duration    = bitstream.ReadBytes(8);
                _bytesRead += 32;
            }
            else
            {
                creationTime     = createDate(bitstream.ReadBytes(4));
                modificationTime = createDate(bitstream.ReadBytes(4));
                trackId          = bitstream.ReadBytes(4);
                bitstream.SkipBytes(4);
                duration    = bitstream.ReadBytes(4);
                _bytesRead += 20;
            }
            bitstream.SkipBytes(8); //reserved by Apple
            int qt_layer          = (int)bitstream.ReadBytes(2);
            int qt_alternateGroup = (int)bitstream.ReadBytes(2);
            int qt_volume         = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Volume: {0}", qt_volume));
#endif
            bitstream.SkipBytes(2); //reserved by Apple
            long qt_matrixA = bitstream.ReadBytes(4);
            long qt_matrixB = bitstream.ReadBytes(4);
            long qt_matrixU = bitstream.ReadBytes(4);
            long qt_matrixC = bitstream.ReadBytes(4);
            long qt_matrixD = bitstream.ReadBytes(4);
            long qt_matrixV = bitstream.ReadBytes(4);
            long qt_matrixX = bitstream.ReadBytes(4);
            long qt_matrixY = bitstream.ReadBytes(4);
            long qt_matrixW = bitstream.ReadBytes(4);
            qt_trackWidth  = (int)bitstream.ReadBytes(4);
            width          = (qt_trackWidth >> 16);
            qt_trackHeight = (int)bitstream.ReadBytes(4);
            height         = (qt_trackHeight >> 16);
            _bytesRead    += 60;
            return(_bytesRead);
        }
示例#16
0
        /// <summary>
        /// Loads SampleDescription atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_sample_description_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
            entryCount = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("stsd entry count: {0}", entryCount));
#endif
            _bytesRead += 4;
            for (int i = 0; i < entryCount; i++)
            {
                Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
                _children.Add(child);
                _bytesRead += child.Size;
            }
            return(_bytesRead);
        }
示例#17
0
        /// <summary>
        /// Creates the PASP atom or Pixel Aspect Ratio. It is created by Quicktime
        /// when exporting an MP4 file. The atom is required for ipod's and acts as
        /// a container for the avcC atom in these cases.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_pasp_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Pixel aspect ratio");
#endif
            int hSpacing = (int)bitstream.ReadBytes(4);
            int vSpacing = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("hSpacing: {0} vSpacing: {1}", hSpacing, vSpacing));
#endif
            _bytesRead += 8;
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return(_bytesRead);
        }
示例#18
0
 /// <summary>
 /// Loads MP4SampleSizeAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_sample_size_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     sampleSize  = (int)bitstream.ReadBytes(4);
     sampleCount = (int)bitstream.ReadBytes(4);
     _bytesRead += 8;
     if (sampleSize == 0)
     {
         for (int i = 0; i < sampleCount; i++)
         {
             int size = (int)bitstream.ReadBytes(4);
             samples.Add(size);
             _bytesRead += 4;
         }
     }
     return(_bytesRead);
 }
示例#19
0
        /// <summary>
        /// Loads MovieHeader atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_movie_header_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
            if (version == 1)
            {
                creationTime     = createDate(bitstream.ReadBytes(8));
                modificationTime = createDate(bitstream.ReadBytes(8));
                timeScale        = (int)bitstream.ReadBytes(4);
                duration         = bitstream.ReadBytes(8);
                _bytesRead      += 28;
            }
            else
            {
                creationTime     = createDate(bitstream.ReadBytes(4));
                modificationTime = createDate(bitstream.ReadBytes(4));
                timeScale        = (int)bitstream.ReadBytes(4);
                duration         = bitstream.ReadBytes(4);
                _bytesRead      += 16;
            }
            int qt_preferredRate   = (int)bitstream.ReadBytes(4);
            int qt_preferredVolume = (int)bitstream.ReadBytes(2);

            bitstream.SkipBytes(10);
            long qt_matrixA           = bitstream.ReadBytes(4);
            long qt_matrixB           = bitstream.ReadBytes(4);
            long qt_matrixU           = bitstream.ReadBytes(4);
            long qt_matrixC           = bitstream.ReadBytes(4);
            long qt_matrixD           = bitstream.ReadBytes(4);
            long qt_matrixV           = bitstream.ReadBytes(4);
            long qt_matrixX           = bitstream.ReadBytes(4);
            long qt_matrixY           = bitstream.ReadBytes(4);
            long qt_matrixW           = bitstream.ReadBytes(4);
            long qt_previewTime       = bitstream.ReadBytes(4);
            long qt_previewDuration   = bitstream.ReadBytes(4);
            long qt_posterTime        = bitstream.ReadBytes(4);
            long qt_selectionTime     = bitstream.ReadBytes(4);
            long qt_selectionDuration = bitstream.ReadBytes(4);
            long qt_currentTime       = bitstream.ReadBytes(4);
            long nextTrackID          = bitstream.ReadBytes(4);

            _bytesRead += 80;
            return(_bytesRead);
        }
示例#20
0
        /// <summary>
        /// Loads MP4SyncSampleAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_sync_sample_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Sync sample atom contains keyframe info");
#endif
            create_full_atom(bitstream);
            entryCount = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("Sync entries: {0}", entryCount));
#endif
            _bytesRead += 4;
            for (int i = 0; i < entryCount; i++)
            {
                int sample = (int)bitstream.ReadBytes(4);
                //log.trace("Sync entry: {}", sample);
                syncSamples.Add(sample);
                _bytesRead += 4;
            }
            return(_bytesRead);
        }
示例#21
0
        /// <summary>
        /// Loads Handler atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_handler_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
            int qt_componentType = (int)bitstream.ReadBytes(4);

            handlerType = (int)bitstream.ReadBytes(4);
            int qt_componentManufacturer = (int)bitstream.ReadBytes(4);
            int qt_componentFlags        = (int)bitstream.ReadBytes(4);
            int qt_componentFlagsMask    = (int)bitstream.ReadBytes(4);

            _bytesRead += 20;
            int    length    = (int)(_size - _bytesRead - 1);
            String trackName = bitstream.ReadString(length);

#if !SILVERLIGHT
            log.Debug(string.Format("Track name: {0}", trackName));
#endif
            _bytesRead += length;
            return(_bytesRead);
        }
示例#22
0
        /// <summary>
        /// Loads MP4VisualSampleEntryAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_visual_sample_entry_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Visual entry atom contains wxh");
#endif
            bitstream.SkipBytes(24);
            width = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Width: {0}", width));
#endif
            height = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Height: {0}", height));
#endif
            bitstream.SkipBytes(50);
            _bytesRead += 78;
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return(_bytesRead);
        }
示例#23
0
        /// <summary>
        /// Loads MP4TimeToSampleAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_time_to_sample_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Time to sample atom");
#endif
            create_full_atom(bitstream);
            entryCount = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("Time to sample entries: {0}", entryCount));
#endif
            _bytesRead += 4;
            for (int i = 0; i < entryCount; i++)
            {
                int sampleCount    = (int)bitstream.ReadBytes(4);
                int sampleDuration = (int)bitstream.ReadBytes(4);
                //log.trace("Sync entry: {}", sample);
                timeToSamplesRecords.Add(new TimeSampleRecord(sampleCount, sampleDuration));
                _bytesRead += 8;
            }
            return(_bytesRead);
        }
示例#24
0
        /// <summary>
        /// Loads CompactSampleSize atom from the input stream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_compact_sample_size_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
            bitstream.SkipBytes(3);
            sampleSize  = 0;
            fieldSize   = (int)bitstream.ReadBytes(1);
            sampleCount = (int)bitstream.ReadBytes(4);
            _bytesRead += 8;
            for (int i = 0; i < sampleCount; i++)
            {
                int size = 0;
                switch (fieldSize)
                {
                case 4:
                    size = (int)bitstream.ReadBytes(1);
                    // TODO check the following code
                    samples.Add(size & 0x0f);
                    size = (size >> 4) & 0x0f;
                    i++;
                    _bytesRead += 1;
                    break;

                case 8:
                    size        = (int)bitstream.ReadBytes(1);
                    _bytesRead += 1;
                    break;

                case 16:
                    size        = (int)bitstream.ReadBytes(2);
                    _bytesRead += 2;
                    break;
                }
                if (i < sampleCount)
                {
                    samples.Add(size);
                }
            }
            return(_bytesRead);
        }
示例#25
0
        /// <summary>
        /// Loads the MP4DecoderConfigDescriptor from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        public void CreateDecoderConfigDescriptor(Mp4DataStream bitstream)
        {
            int  objectTypeIndication = (int)bitstream.ReadBytes(1);
            int  value      = (int)bitstream.ReadBytes(1);
            bool upstream   = (value & (1 << 1)) > 0;
            byte streamType = (byte)(value >> 2);

            value = (int)bitstream.ReadBytes(2);
            int bufferSizeDB = value << 8;

            value         = (int)bitstream.ReadBytes(1);
            bufferSizeDB |= value & 0xff;
            int maxBitRate = (int)bitstream.ReadBytes(4);
            int minBitRate = (int)bitstream.ReadBytes(4);

            _bytesRead += 13;
            if (_bytesRead < _size)
            {
                Mp4Descriptor descriptor = CreateDescriptor(bitstream);
                _children.Add(descriptor);
                _bytesRead += descriptor.BytesRead;
            }
        }
示例#26
0
        public static Mp4Descriptor CreateDescriptor(Mp4DataStream bitstream)
        {
            int tag       = (int)bitstream.ReadBytes(1);
            int bytesRead = 1;
            int size      = 0;
            int b         = 0;

            do
            {
                b      = (int)bitstream.ReadBytes(1);
                size <<= 7;
                size  |= b & 0x7f;
                bytesRead++;
            } while ((b & 0x80) == 0x80);
            Mp4Descriptor descriptor = new Mp4Descriptor(tag, size);

            switch (tag)
            {
            case MP4ES_DescriptorTag:
                descriptor.CreateESDescriptor(bitstream);
                break;

            case MP4DecoderConfigDescriptorTag:
                descriptor.CreateDecoderConfigDescriptor(bitstream);
                break;

            case MP4DecSpecificInfoDescriptorTag:
                descriptor.CreateDecSpecificInfoDescriptor(bitstream);
                break;

            default:
                break;
            }
            bitstream.SkipBytes(descriptor._size - descriptor._bytesRead);
            descriptor._bytesRead = bytesRead + descriptor._size;
            return(descriptor);
        }
示例#27
0
 /// <summary>
 /// Loads MediaHeader atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_media_header_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     if (version == 1)
     {
         creationTime = createDate(bitstream.ReadBytes(8));
         modificationTime = createDate(bitstream.ReadBytes(8));
         timeScale = (int)bitstream.ReadBytes(4);
         duration = bitstream.ReadBytes(8);
         _bytesRead += 28;
     }
     else
     {
         creationTime = createDate(bitstream.ReadBytes(4));
         modificationTime = createDate(bitstream.ReadBytes(4));
         timeScale = (int)bitstream.ReadBytes(4);
         duration = bitstream.ReadBytes(4);
         _bytesRead += 16;
     }
     int packedLanguage = (int)bitstream.ReadBytes(2);
     int qt_quality = (int)bitstream.ReadBytes(2);
     _bytesRead += 4;
     return _bytesRead;
 }
示例#28
0
 /// <summary>
 /// Loads ChunkOffset atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_chunk_offset_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     entryCount = (int)bitstream.ReadBytes(4);
     _bytesRead += 4;
     for (int i = 0; i < entryCount; i++)
     {
         long chunkOffset = bitstream.ReadBytes(4);
         chunks.Add(chunkOffset);
         _bytesRead += 4;
     }
     return _bytesRead;
 }
示例#29
0
        /// <summary>
        /// Loads Handler atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_handler_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
            int qt_componentType = (int)bitstream.ReadBytes(4);
            handlerType = (int)bitstream.ReadBytes(4);
            int qt_componentManufacturer = (int)bitstream.ReadBytes(4);
            int qt_componentFlags = (int)bitstream.ReadBytes(4);
            int qt_componentFlagsMask = (int)bitstream.ReadBytes(4);
            _bytesRead += 20;
            int length = (int)(_size - _bytesRead - 1);
            String trackName = bitstream.ReadString(length);
#if !SILVERLIGHT
            log.Debug(string.Format("Track name: {0}", trackName));
#endif
            _bytesRead += length;
            return _bytesRead;
        }
示例#30
0
 /// <summary>
 /// Loads the composite atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_composite_atom(Mp4DataStream bitstream)
 {
     while (_bytesRead < _size)
     {
         Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
         _children.Add(child);
         _bytesRead += child.Size;
     }
     return _bytesRead;
 }
示例#31
0
        /// <summary>
        /// Loads AudioSampleEntry atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_audio_sample_entry_atom(Mp4DataStream bitstream)
        {
            //qtff page 117
#if !SILVERLIGHT
            log.Debug("Audio sample entry");
#endif
            bitstream.SkipBytes(6);
            int dataReferenceIndex = (int)bitstream.ReadBytes(2);
            bitstream.SkipBytes(8);
            channelCount = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Channels: {0}", channelCount));
#endif
            sampleSize = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Sample size (bits): {0}", sampleSize));
#endif
            bitstream.SkipBytes(4);
            timeScale = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Time scale: {0}", timeScale));
#endif
            bitstream.SkipBytes(2);
            _bytesRead += 28;
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return _bytesRead;
        }
示例#32
0
 /// <summary>
 /// Loads MP4SampleSizeAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_sample_size_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     sampleSize = (int)bitstream.ReadBytes(4);
     sampleCount = (int)bitstream.ReadBytes(4);
     _bytesRead += 8;
     if (sampleSize == 0)
     {
         for (int i = 0; i < sampleCount; i++)
         {
             int size = (int)bitstream.ReadBytes(4);
             samples.Add(size);
             _bytesRead += 4;
         }
     }
     return _bytesRead;
 }
示例#33
0
 /// <summary>
 /// Loads the version of the full atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_full_atom(Mp4DataStream bitstream)
 {
     long value = bitstream.ReadBytes(4);
     version = (int)value >> 24;
     flags = (int)value & 0xffffff;
     _bytesRead += 4;
     return _bytesRead;
 }
示例#34
0
        /// <summary>
        /// Creates the PASP atom or Pixel Aspect Ratio. It is created by Quicktime
        /// when exporting an MP4 file. The atom is required for ipod's and acts as
        /// a container for the avcC atom in these cases.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_pasp_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Pixel aspect ratio");
#endif
            int hSpacing = (int)bitstream.ReadBytes(4);
            int vSpacing = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("hSpacing: {0} vSpacing: {1}", hSpacing, vSpacing));
#endif
            _bytesRead += 8;
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return _bytesRead;
        }
示例#35
0
 /// <summary>
 /// Loads M4ESDAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_esd_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     esd_descriptor = Mp4Descriptor.CreateDescriptor(bitstream);
     _bytesRead += esd_descriptor.BytesRead;
     return _bytesRead;
 }
示例#36
0
        /// <summary>
        /// Loads MP4VisualSampleEntryAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_visual_sample_entry_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Visual entry atom contains wxh");
#endif
            bitstream.SkipBytes(24);
            width = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Width: {0}", width));
#endif
            height = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Height: {0}", height));
#endif
            bitstream.SkipBytes(50);
            _bytesRead += 78;
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return _bytesRead;
        }
示例#37
0
 public Mp4Reader(Stream stream)
 {
     _stream = stream;
     _inputStream = new Mp4DataStream(_stream);
 }
示例#38
0
        /// <summary>
        /// Loads MP4TrackHeaderAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_track_header_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
#if !SILVERLIGHT
            log.Debug(string.Format("Version: {0}", version));
#endif
            if (version == 1)
            {
                creationTime = createDate(bitstream.ReadBytes(8));
                modificationTime = createDate(bitstream.ReadBytes(8));
                trackId = bitstream.ReadBytes(4);
                bitstream.SkipBytes(4);
                duration = bitstream.ReadBytes(8);
                _bytesRead += 32;
            }
            else
            {
                creationTime = createDate(bitstream.ReadBytes(4));
                modificationTime = createDate(bitstream.ReadBytes(4));
                trackId = bitstream.ReadBytes(4);
                bitstream.SkipBytes(4);
                duration = bitstream.ReadBytes(4);
                _bytesRead += 20;
            }
            bitstream.SkipBytes(8); //reserved by Apple
            int qt_layer = (int)bitstream.ReadBytes(2);
            int qt_alternateGroup = (int)bitstream.ReadBytes(2);
            int qt_volume = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Volume: {0}", qt_volume));
#endif
            bitstream.SkipBytes(2); //reserved by Apple
            long qt_matrixA = bitstream.ReadBytes(4);
            long qt_matrixB = bitstream.ReadBytes(4);
            long qt_matrixU = bitstream.ReadBytes(4);
            long qt_matrixC = bitstream.ReadBytes(4);
            long qt_matrixD = bitstream.ReadBytes(4);
            long qt_matrixV = bitstream.ReadBytes(4);
            long qt_matrixX = bitstream.ReadBytes(4);
            long qt_matrixY = bitstream.ReadBytes(4);
            long qt_matrixW = bitstream.ReadBytes(4);
            qt_trackWidth = (int)bitstream.ReadBytes(4);
            width = (qt_trackWidth >> 16);
            qt_trackHeight = (int)bitstream.ReadBytes(4);
            height = (qt_trackHeight >> 16);
            _bytesRead += 60;
            return _bytesRead;
        }
示例#39
0
        /// <summary>
        /// Loads MP4TimeToSampleAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_time_to_sample_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Time to sample atom");
#endif
            create_full_atom(bitstream);
            entryCount = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("Time to sample entries: {0}", entryCount));
#endif
            _bytesRead += 4;
            for (int i = 0; i < entryCount; i++)
            {
                int sampleCount = (int)bitstream.ReadBytes(4);
                int sampleDuration = (int)bitstream.ReadBytes(4);
                //log.trace("Sync entry: {}", sample);
                timeToSamplesRecords.Add(new TimeSampleRecord(sampleCount, sampleDuration));
                _bytesRead += 8;
            }
            return _bytesRead;
        }
示例#40
0
 /// <summary>
 /// Loads MP4SampleToChunkAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_sample_to_chunk_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     entryCount = (int)bitstream.ReadBytes(4);
     _bytesRead += 4;
     for (int i = 0; i < entryCount; i++)
     {
         int firstChunk = (int)bitstream.ReadBytes(4);
         int samplesPerChunk = (int)bitstream.ReadBytes(4);
         int sampleDescriptionIndex = (int)bitstream.ReadBytes(4);
         records.Add(new Record(firstChunk, samplesPerChunk, sampleDescriptionIndex));
         _bytesRead += 12;
     }
     return _bytesRead;
 }
示例#41
0
 /// <summary>
 /// Loads MovieHeader atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_movie_header_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     if (version == 1)
     {
         creationTime = createDate(bitstream.ReadBytes(8));
         modificationTime = createDate(bitstream.ReadBytes(8));
         timeScale = (int)bitstream.ReadBytes(4);
         duration = bitstream.ReadBytes(8);
         _bytesRead += 28;
     }
     else
     {
         creationTime = createDate(bitstream.ReadBytes(4));
         modificationTime = createDate(bitstream.ReadBytes(4));
         timeScale = (int)bitstream.ReadBytes(4);
         duration = bitstream.ReadBytes(4);
         _bytesRead += 16;
     }
     int qt_preferredRate = (int)bitstream.ReadBytes(4);
     int qt_preferredVolume = (int)bitstream.ReadBytes(2);
     bitstream.SkipBytes(10);
     long qt_matrixA = bitstream.ReadBytes(4);
     long qt_matrixB = bitstream.ReadBytes(4);
     long qt_matrixU = bitstream.ReadBytes(4);
     long qt_matrixC = bitstream.ReadBytes(4);
     long qt_matrixD = bitstream.ReadBytes(4);
     long qt_matrixV = bitstream.ReadBytes(4);
     long qt_matrixX = bitstream.ReadBytes(4);
     long qt_matrixY = bitstream.ReadBytes(4);
     long qt_matrixW = bitstream.ReadBytes(4);
     long qt_previewTime = bitstream.ReadBytes(4);
     long qt_previewDuration = bitstream.ReadBytes(4);
     long qt_posterTime = bitstream.ReadBytes(4);
     long qt_selectionTime = bitstream.ReadBytes(4);
     long qt_selectionDuration = bitstream.ReadBytes(4);
     long qt_currentTime = bitstream.ReadBytes(4);
     long nextTrackID = bitstream.ReadBytes(4);
     _bytesRead += 80;
     return _bytesRead;
 }
示例#42
0
        /// <summary>
        /// Constructs an Atom object from the data in the bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The constructed atom.</returns>
        public static Mp4Atom CreateAtom(Mp4DataStream bitstream)
        {
            String uuid = null;
            long size = bitstream.ReadBytes(4);
            if (size == 0)
            {
                throw new IOException("Invalid size");
            }
            int type = (int)bitstream.ReadBytes(4);
            long bytesRead = 8;
            if (type == MP4ExtendedAtomType)
            {
                uuid = bitstream.ReadString(16);
                bytesRead += 16;
            }
            // large size
            if (size == 1)
            {
                size = bitstream.ReadBytes(8);
                bytesRead += 8;
            }
            Mp4Atom atom = new Mp4Atom(size, type, uuid, bytesRead);
            if ((type == MP4MediaAtomType) || (type == MP4DataInformationAtomType) || (type == MP4MovieAtomType)
                || (type == MP4MediaInformationAtomType) || (type == MP4SampleTableAtomType) || (type == MP4TrackAtomType))
            {
                bytesRead = atom.create_composite_atom(bitstream);
            }
            else if (type == MP4AudioSampleEntryAtomType)
            {
                bytesRead = atom.create_audio_sample_entry_atom(bitstream);
            }
            else if (type == MP4ChunkLargeOffsetAtomType)
            {
                bytesRead = atom.create_chunk_large_offset_atom(bitstream);
            }
            else if (type == MP4ChunkOffsetAtomType)
            {
                bytesRead = atom.create_chunk_offset_atom(bitstream);
            }
            else if (type == MP4HandlerAtomType)
            {
                bytesRead = atom.create_handler_atom(bitstream);
            }
            else if (type == MP4MediaHeaderAtomType)
            {
                bytesRead = atom.create_media_header_atom(bitstream);
            }
            else if (type == MP4MovieHeaderAtomType)
            {
                bytesRead = atom.create_movie_header_atom(bitstream);
            }
            else if (type == MP4SampleDescriptionAtomType)
            {
                bytesRead = atom.create_sample_description_atom(bitstream);
            }
            else if (type == MP4SampleSizeAtomType)
            {
                bytesRead = atom.create_sample_size_atom(bitstream);
            }
            else if (type == MP4CompactSampleSizeAtomType)
            {
                bytesRead = atom.create_compact_sample_size_atom(bitstream);
            }
            else if (type == MP4SampleToChunkAtomType)
            {
                bytesRead = atom.create_sample_to_chunk_atom(bitstream);
            }
            else if (type == MP4SyncSampleAtomType)
            {
                bytesRead = atom.create_sync_sample_atom(bitstream);
            }
            else if (type == MP4TimeToSampleAtomType)
            {
                bytesRead = atom.create_time_to_sample_atom(bitstream);
            }
            else if (type == MP4SoundMediaHeaderAtomType)
            {
                bytesRead = atom.create_sound_media_header_atom(bitstream);
            }
            else if (type == MP4TrackHeaderAtomType)
            {
                bytesRead = atom.create_track_header_atom(bitstream);
            }
            else if (type == MP4VideoMediaHeaderAtomType)
            {
                bytesRead = atom.create_video_media_header_atom(bitstream);
            }
            else if (type == MP4VisualSampleEntryAtomType)
            {
                bytesRead = atom.create_visual_sample_entry_atom(bitstream);
            }
            else if (type == MP4VideoSampleEntryAtomType)
            {
                bytesRead = atom.create_video_sample_entry_atom(bitstream);
            }
            else if (type == MP4ESDAtomType)
            {
                bytesRead = atom.create_esd_atom(bitstream);
            }
            else if (type == MP4AVCAtomType)
            {
                bytesRead = atom.create_avc_config_atom(bitstream);
            }
            else if (type == MP4PixelAspectAtomType)
            {
                bytesRead = atom.create_pasp_atom(bitstream);
            }
#if !SILVERLIGHT
            log.Debug(string.Format("Atom: type = {0} size = {1}", IntToType(type), size));
#endif
            bitstream.SkipBytes(size - bytesRead);
            return atom;
        }
示例#43
0
        /// <summary>
        /// Loads SampleDescription atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_sample_description_atom(Mp4DataStream bitstream)
        {
            create_full_atom(bitstream);
            entryCount = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("stsd entry count: {0}", entryCount));
#endif
            _bytesRead += 4;
            for (int i = 0; i < entryCount; i++)
            {
                Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
                _children.Add(child);
                _bytesRead += child.Size;
            }
            return _bytesRead;
        }
示例#44
0
 /// <summary>
 /// Creates MP4 reader from file input stream, sets up metadata generation flag.
 /// </summary>
 /// <param name="file"></param>
 public Mp4Reader(FileInfo file)
 {
     //_file = file;
     _stream = new FileStream(file.FullName, FileMode.Open);
     _inputStream = new Mp4DataStream(_stream);
     //Decode all the info that we want from the atoms
     DecodeHeader();
     //Analyze the samples/chunks and build the keyframe meta data
     AnalyzeFrames();
     //Add meta data
     _firstTags.AddLast(CreateFileMeta());
     //Create / add the pre-streaming (decoder config) tags
     CreatePreStreamingTags();
 }
示例#45
0
 /// <summary>
 /// Loads CompactSampleSize atom from the input stream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_compact_sample_size_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     bitstream.SkipBytes(3);
     sampleSize = 0;
     fieldSize = (int)bitstream.ReadBytes(1);
     sampleCount = (int)bitstream.ReadBytes(4);
     _bytesRead += 8;
     for (int i = 0; i < sampleCount; i++)
     {
         int size = 0;
         switch (fieldSize)
         {
             case 4:
                 size = (int)bitstream.ReadBytes(1);
                 // TODO check the following code
                 samples.Add(size & 0x0f);
                 size = (size >> 4) & 0x0f;
                 i++;
                 _bytesRead += 1;
                 break;
             case 8:
                 size = (int)bitstream.ReadBytes(1);
                 _bytesRead += 1;
                 break;
             case 16:
                 size = (int)bitstream.ReadBytes(2);
                 _bytesRead += 2;
                 break;
         }
         if (i < sampleCount)
         {
             samples.Add(size);
         }
     }
     return _bytesRead;
 }
示例#46
0
 /// <summary>
 /// Loads the MP4ES_Descriptor from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 public void CreateESDescriptor(Mp4DataStream bitstream)
 {
     int ES_ID = (int)bitstream.ReadBytes(2);
     int flags = (int)bitstream.ReadBytes(1);
     bool streamDependenceFlag = (flags & (1 << 7)) != 0;
     bool urlFlag = (flags & (1 << 6)) != 0;
     bool ocrFlag = (flags & (1 << 5)) != 0;
     _bytesRead += 3;
     if (streamDependenceFlag)
     {
         bitstream.SkipBytes(2);
         _bytesRead += 2;
     }
     if (urlFlag)
     {
         int str_size = (int)bitstream.ReadBytes(1);
         bitstream.ReadString(str_size);
         _bytesRead += str_size + 1;
     }
     if (ocrFlag)
     {
         bitstream.SkipBytes(2);
         _bytesRead += 2;
     }
     while (_bytesRead < _size)
     {
         Mp4Descriptor descriptor = CreateDescriptor(bitstream);
         _children.Add(descriptor);
         _bytesRead += descriptor.BytesRead;
     }
 }
示例#47
0
        /// <summary>
        /// Loads MP4SyncSampleAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_sync_sample_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Sync sample atom contains keyframe info");
#endif
            create_full_atom(bitstream);
            entryCount = (int)bitstream.ReadBytes(4);
#if !SILVERLIGHT
            log.Debug(string.Format("Sync entries: {0}", entryCount));
#endif
            _bytesRead += 4;
            for (int i = 0; i < entryCount; i++)
            {
                int sample = (int)bitstream.ReadBytes(4);
                //log.trace("Sync entry: {}", sample);
                syncSamples.Add(sample);
                _bytesRead += 4;
            }
            return _bytesRead;
        }
示例#48
0
 /// <summary>
 /// Loads the MP4DecoderConfigDescriptor from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 public void CreateDecoderConfigDescriptor(Mp4DataStream bitstream)
 {
     int objectTypeIndication = (int)bitstream.ReadBytes(1);
     int value = (int)bitstream.ReadBytes(1);
     bool upstream = (value & (1 << 1)) > 0;
     byte streamType = (byte)(value >> 2);
     value = (int)bitstream.ReadBytes(2);
     int bufferSizeDB = value << 8;
     value = (int)bitstream.ReadBytes(1);
     bufferSizeDB |= value & 0xff;
     int maxBitRate = (int)bitstream.ReadBytes(4);
     int minBitRate = (int)bitstream.ReadBytes(4);
     _bytesRead += 13;
     if (_bytesRead < _size)
     {
         Mp4Descriptor descriptor = CreateDescriptor(bitstream);
         _children.Add(descriptor);
         _bytesRead += descriptor.BytesRead;
     }
 }
示例#49
0
 /// <summary>
 /// Loads MP4SoundMediaHeaderAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_sound_media_header_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     balance = (int)bitstream.ReadBytes(2);
     bitstream.SkipBytes(2);
     _bytesRead += 4;
     return _bytesRead;
 }
示例#50
0
 public void CreateDecSpecificInfoDescriptor(Mp4DataStream bitstream)
 {
     decSpecificDataOffset = bitstream.Offset;
     dsid = new byte[_size];
     for (int b = 0; b < _size; b++)
     {
         dsid[b] = (byte)bitstream.ReadBytes(1);
         _bytesRead++;
     }
     decSpecificDataSize = _size - _bytesRead;
 }
示例#51
0
 /// <summary>
 /// Loads MP4VideoMediaHeaderAtom atom from the input bitstream.
 /// </summary>
 /// <param name="bitstream">The input bitstream.</param>
 /// <returns>The number of bytes loaded.</returns>
 public long create_video_media_header_atom(Mp4DataStream bitstream)
 {
     create_full_atom(bitstream);
     if ((_size - _bytesRead) == 8)
     {
         graphicsMode = (int)bitstream.ReadBytes(2);
         opColorRed = (int)bitstream.ReadBytes(2);
         opColorGreen = (int)bitstream.ReadBytes(2);
         opColorBlue = (int)bitstream.ReadBytes(2);
         _bytesRead += 8;
     }
     return _bytesRead;
 }
示例#52
0
        /// <summary>
        /// Loads AVCC atom from the input bitstream.
        /// <para>
        /// 8+ bytes ISO/IEC 14496-10 or 3GPP AVC decode config box
        ///  = long unsigned offset + long ASCII text string 'avcC'
        /// -> 1 byte version = 8-bit hex version  (current = 1)
        /// -> 1 byte H.264 profile = 8-bit unsigned stream profile
        /// -> 1 byte H.264 compatible profiles = 8-bit hex flags
        /// -> 1 byte H.264 level = 8-bit unsigned stream level
        /// -> 1 1/2 nibble reserved = 6-bit unsigned value set to 63
        /// -> 1/2 nibble NAL length = 2-bit length byte size type
        ///  - 1 byte = 0 ; 2 bytes = 1 ; 4 bytes = 3
        /// -> 1 byte number of SPS = 8-bit unsigned total
        /// -> 2+ bytes SPS length = short unsigned length
        /// -> + SPS NAL unit = hexdump
        /// -> 1 byte number of PPS = 8-bit unsigned total
        /// -> 2+ bytes PPS length = short unsigned length
        /// -> + PPS NAL unit = hexdump 
        /// </para>
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_avc_config_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("AVC config");
            log.Debug(string.Format("Offset: {0}", bitstream.Offset));
#endif
            //store the decoder config bytes
            videoConfigBytes = new byte[(int)_size];
            for (int b = 0; b < videoConfigBytes.Length; b++)
            {
                videoConfigBytes[b] = (byte)bitstream.ReadBytes(1);
                switch (b)
                {
                    //0 / version
                    case 1: //profile
                        avcProfile = videoConfigBytes[b];
#if !SILVERLIGHT
                        log.Debug(string.Format("AVC profile: {0}", avcProfile));
#endif
                        break;
                    case 2: //compatible profile
                        int avcCompatProfile = videoConfigBytes[b];
#if !SILVERLIGHT
                        log.Debug(string.Format("AVC compatible profile: {0}", avcCompatProfile));
#endif
                        break;
                    case 3: //avc level
                        avcLevel = videoConfigBytes[b];
#if !SILVERLIGHT
                        log.Debug(string.Format("AVC level: {0}", avcLevel));
#endif
                        break;
                    case 4: //NAL length
                        break;
                    case 5: //SPS number
                        int numberSPS = videoConfigBytes[b];
#if !SILVERLIGHT
                        log.Debug(string.Format("Number of SPS: {0}", numberSPS));
#endif
                        break;
                    default:
                        break;
                }
                _bytesRead++;
            }
            return _bytesRead;
        }
示例#53
0
        /// <summary>
        /// Loads MP4VideoSampleEntryAtom atom from the input bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The number of bytes loaded.</returns>
        public long create_video_sample_entry_atom(Mp4DataStream bitstream)
        {
#if !SILVERLIGHT
            log.Debug("Video entry atom contains wxh");
#endif
            bitstream.SkipBytes(6);
            int dataReferenceIndex = (int)bitstream.ReadBytes(2);
            bitstream.SkipBytes(2);
            bitstream.SkipBytes(2);
            bitstream.SkipBytes(12);
            width = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Width: {0}", width));
#endif
            height = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Height: {0}", height));
#endif
            int horizontalRez = (int)bitstream.ReadBytes(4) >> 16;
#if !SILVERLIGHT
            log.Debug(string.Format("H Resolution: {0}", horizontalRez));
#endif
            int verticalRez = (int)bitstream.ReadBytes(4) >> 16;
#if !SILVERLIGHT
            log.Debug(string.Format("V Resolution: {0}", verticalRez));
#endif
            bitstream.SkipBytes(4);
            int frameCount = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Frame to sample count: {0}", frameCount));
#endif
            int stringLen = (int)bitstream.ReadBytes(1);
#if !SILVERLIGHT
            log.Debug(string.Format("String length (cpname): {0}", stringLen));
#endif
            String compressorName = bitstream.ReadString(31);
#if !SILVERLIGHT
            log.Debug(string.Format("Compressor name: {0}", compressorName.Trim()));
#endif
            int depth = (int)bitstream.ReadBytes(2);
#if !SILVERLIGHT
            log.Debug(string.Format("Depth: {0}", depth));
#endif
            bitstream.SkipBytes(2);
            _bytesRead += 78;
#if !SILVERLIGHT
            log.Debug(string.Format("Bytes read: {0}", _bytesRead));
#endif
            Mp4Atom child = Mp4Atom.CreateAtom(bitstream);
            _children.Add(child);
            _bytesRead += child.Size;
            return _bytesRead;
        }
示例#54
0
        /// <summary>
        /// Constructs an Atom object from the data in the bitstream.
        /// </summary>
        /// <param name="bitstream">The input bitstream.</param>
        /// <returns>The constructed atom.</returns>
        public static Mp4Atom CreateAtom(Mp4DataStream bitstream)
        {
            String uuid = null;
            long   size = bitstream.ReadBytes(4);

            if (size == 0)
            {
                throw new IOException("Invalid size");
            }
            int  type      = (int)bitstream.ReadBytes(4);
            long bytesRead = 8;

            if (type == MP4ExtendedAtomType)
            {
                uuid       = bitstream.ReadString(16);
                bytesRead += 16;
            }
            // large size
            if (size == 1)
            {
                size       = bitstream.ReadBytes(8);
                bytesRead += 8;
            }
            Mp4Atom atom = new Mp4Atom(size, type, uuid, bytesRead);

            if ((type == MP4MediaAtomType) || (type == MP4DataInformationAtomType) || (type == MP4MovieAtomType) ||
                (type == MP4MediaInformationAtomType) || (type == MP4SampleTableAtomType) || (type == MP4TrackAtomType))
            {
                bytesRead = atom.create_composite_atom(bitstream);
            }
            else if (type == MP4AudioSampleEntryAtomType)
            {
                bytesRead = atom.create_audio_sample_entry_atom(bitstream);
            }
            else if (type == MP4ChunkLargeOffsetAtomType)
            {
                bytesRead = atom.create_chunk_large_offset_atom(bitstream);
            }
            else if (type == MP4ChunkOffsetAtomType)
            {
                bytesRead = atom.create_chunk_offset_atom(bitstream);
            }
            else if (type == MP4HandlerAtomType)
            {
                bytesRead = atom.create_handler_atom(bitstream);
            }
            else if (type == MP4MediaHeaderAtomType)
            {
                bytesRead = atom.create_media_header_atom(bitstream);
            }
            else if (type == MP4MovieHeaderAtomType)
            {
                bytesRead = atom.create_movie_header_atom(bitstream);
            }
            else if (type == MP4SampleDescriptionAtomType)
            {
                bytesRead = atom.create_sample_description_atom(bitstream);
            }
            else if (type == MP4SampleSizeAtomType)
            {
                bytesRead = atom.create_sample_size_atom(bitstream);
            }
            else if (type == MP4CompactSampleSizeAtomType)
            {
                bytesRead = atom.create_compact_sample_size_atom(bitstream);
            }
            else if (type == MP4SampleToChunkAtomType)
            {
                bytesRead = atom.create_sample_to_chunk_atom(bitstream);
            }
            else if (type == MP4SyncSampleAtomType)
            {
                bytesRead = atom.create_sync_sample_atom(bitstream);
            }
            else if (type == MP4TimeToSampleAtomType)
            {
                bytesRead = atom.create_time_to_sample_atom(bitstream);
            }
            else if (type == MP4SoundMediaHeaderAtomType)
            {
                bytesRead = atom.create_sound_media_header_atom(bitstream);
            }
            else if (type == MP4TrackHeaderAtomType)
            {
                bytesRead = atom.create_track_header_atom(bitstream);
            }
            else if (type == MP4VideoMediaHeaderAtomType)
            {
                bytesRead = atom.create_video_media_header_atom(bitstream);
            }
            else if (type == MP4VisualSampleEntryAtomType)
            {
                bytesRead = atom.create_visual_sample_entry_atom(bitstream);
            }
            else if (type == MP4VideoSampleEntryAtomType)
            {
                bytesRead = atom.create_video_sample_entry_atom(bitstream);
            }
            else if (type == MP4ESDAtomType)
            {
                bytesRead = atom.create_esd_atom(bitstream);
            }
            else if (type == MP4AVCAtomType)
            {
                bytesRead = atom.create_avc_config_atom(bitstream);
            }
            else if (type == MP4PixelAspectAtomType)
            {
                bytesRead = atom.create_pasp_atom(bitstream);
            }
#if !SILVERLIGHT
            log.Debug(string.Format("Atom: type = {0} size = {1}", IntToType(type), size));
#endif
            bitstream.SkipBytes(size - bytesRead);
            return(atom);
        }