Beispiel #1
0
        private Fragment GetNextAudioFrag()
        {
            if (nextAudioFragPosition < 0)
            {
                return(null);                       // there are no more!!
            }
            boxReader.BaseStream.Position = nextAudioFragPosition;

            // we know where at least the next frag is as we prepared this prior to the call of this function...
            Fragment answer = new Fragment(GetTimeScale(audioTrackID), GetPayloadType(audioTrackID), runningTimeIn100NanoSecs, runningSliceIndex);

            answer.Read(boxReader);
            runningTimeIn100NanoSecs += (ulong)TimeArithmetic.ConvertToStandardUnit(answer.TimeScale, (decimal)answer.Duration);
            runningSliceIndex        += answer.Length;

            nextAudioFragPosition = -1;
            while (this.boxReader.PeekNextBoxType() == BoxTypes.MovieFragment)
            {
                long     fragPos = boxReader.BaseStream.Position;
                Fragment tmp     = new Fragment();

                int trakID = (int)tmp.GetMP4TrackID(boxReader);
                if (GetFragmentHandlerType(trakID) == "soun")
                {
                    nextAudioFragPosition = fragPos;
                    break;
                }
            }

            return(answer);
        }
Beispiel #2
0
        /// <summary>
        /// GetStartAndEndIndex
        /// Given a start time and an end time, determine the start slice index and end slice index.
        /// </summary>
        /// <param name="edtsBox"EditsBox></param>
        /// <param name="sampleTimeScale">uint - sample time scale</param>
        /// <param name="startTime">ulong - start time</param>
        /// <param name="endTime">ulong - end time</param>
        /// <param name="startIndex">out param: start index</param>
        /// <param name="endIndex">out param: end index</param>
        private void GetStartAndEndIndex(EdtsBox edtsBox, uint sampleTimeScale, ulong startTime, ulong endTime, out uint startIndex, out uint endIndex)
        {
            startIndex = 0;
            endIndex   = 0;

            ulong ticksDuration = (ulong)TimeArithmetic.ConvertToStandardUnit(sampleTimeScale, parent.parent.MediaHeaderBox.Duration);

            if (edtsBox != null)
            {
                ticksDuration = (ulong)(edtsBox.GetEditTrackDuration(sampleTimeScale) * (decimal)TimeSpan.TicksPerSecond);
            }
            if (ticksDuration < startTime)
            {
                return;
            }

            DecodingTimeToSampleBox stts = this.DecodingTimeToSampleBox;
            SyncSampleMapBox        stss = this.SyncSampleMapBox;

            uint  sampleCount = 0;
            ulong timeT       = 0;
            ulong currScaledT = 0;
            ulong prevScaledT = 0;

            uint[] counts     = stts.SampleCount;
            uint[] deltaTimes = stts.SampleDelta;
            bool   startSet   = false;


            for (int i = 0; i < stts.EntryCount; i++)
            {
                for (int j = 0; j < counts[i]; j++)
                {
                    if ((currScaledT >= startTime) && (!startSet) && ((stss == null) || (stss.IsIFrame(sampleCount + 1))))
                    {
                        startSet   = true;
                        startIndex = sampleCount + 1;
                    }

                    if (((stss == null) || stss.IsIFrame(sampleCount + 2)) && (currScaledT > endTime))
                    {
                        endIndex = sampleCount + 1;
                        break;
                    } // close of if (currScaledT > endTime)

                    prevScaledT = currScaledT;
                    timeT      += deltaTimes[i];
                    sampleCount++;
                    currScaledT = (ulong)TimeArithmetic.ConvertToStandardUnit(sampleTimeScale, timeT);
                } // end of for j

                if (endIndex > 0) // end sample found
                {
                    break;
                }
            } // end of for i

            if ((endIndex == 0) && startSet) // end sample not found
            {
                endIndex = sampleCount + 1;
            }
        }
Beispiel #3
0
        /// <summary>
        /// GetOneSample
        /// Get one frame or sample from the moof structures. There is no stss in a fragment, so we need to determine
        /// whether a frame is an IFrame or not by examining the IndependentAndDisposableSamplesBox.
        /// </summary>
        /// <param name="samples"></param>
        /// <param name="tfhd"></param>
        /// <returns></returns>
        private StreamDataBlockInfo GetOneSample(List <TrackFragmentRunSample> samples, TrackFragmentHeaderBox tfhd)
        {
            if (_currentFrame == samples.Count + _startIndex)
            {
                return(null);
            }

            uint fixedFrameSizeInBytes = tfhd.DefaultSampleSize;

            if (fixedFrameSizeInBytes == 0)
            {
                fixedFrameSizeInBytes = samples[_currentFrame - _startIndex].SampleSize;
            }

            if (fixedFrameSizeInBytes == 0) // if it's still zero, then we have a problem
            {
                throw new Exception("Sample size zero");
            }

            // is there enough data left to read the next frame?
            if (this._baseDataOffset + _currentOffsetInBytes + fixedFrameSizeInBytes > (ulong)_reader.BaseStream.Length)
            {
                return(null);
            }

            // currently DRM is not yet supported in this GetFrame routine, unlike the FragmentedMp4ParserImplementation
            //        if ((this.m_drmIVOffsets != null) && (this.m_numDrmIVs > this.m_frameIndex))
            //        {
            //            length = this.m_drmIVSizes[this.m_frameIndex];
            //            destinationArray = new byte[length];
            //            Array.Copy(this.m_headerBuffer, this.m_drmIVOffsets[this.m_frameIndex], destinationArray, 0, length);
            //        }

            uint fixedDuration = tfhd.DefaultSampleDuration;

            if (samples[_currentFrame - _startIndex].SampleDuration != 0)
            {
                fixedDuration = samples[_currentFrame - _startIndex].SampleDuration;
            }
            if (_timeScale > 0) // time scale is 1 for ODS assets
            {
                // scale time
                fixedDuration = (uint)TimeArithmetic.ConvertToStandardUnit(_timeScale, fixedDuration);
            }

            StreamDataBlockInfo oneFrameData = new StreamDataBlockInfo();

            //RawFrameData ans = new RawFrameData(CurrentTime, currentOffsetInBytes, fixedFrameSizeInBytes, fixedDuration, destinationArray);
            oneFrameData.SliceDuration = fixedDuration;
            oneFrameData.SliceSize     = (int)fixedFrameSizeInBytes;
            oneFrameData.StreamOffset  = this._baseDataOffset + _currentOffsetInBytes;
            GetSliceTypeAndFrameNum(oneFrameData);

            // for ISM, TimeStampNew will always have a value
            oneFrameData.TimeStampNew = (ulong)_currentTime;
            oneFrameData.index        = _currentFrame;

            _currentOffsetInBytes += fixedFrameSizeInBytes;
            _currentTime          += fixedDuration;
            _currentFrame++;

            return(oneFrameData);
        }
Beispiel #4
0
        public override void LazyRead(int requestedBoxCount)
        {
            //this.m_reader.BaseStream.Seek(0L, SeekOrigin.Begin);

            BoxType boxType;

            while (this.m_reader.BaseStream.Position < this.m_reader.BaseStream.Length)
            {
                boxType = this.m_reader.PeekNextBoxType();
                if (boxType == BoxTypes.MovieFragment)
                {
                    IsMediaStreamFragmented = true;
                    break; // don't process fragment here, do it in the ISMV class (which is derived from this one)
                }
                else if (boxType == BoxTypes.FileType)
                {
                    ftb = new FileTypeBox();
                    ftb.Read(this.m_reader);
                    Hints.CompatibleBrands = ftb.CompatibleBrands;
                }
                else if (boxType == BoxTypes.Movie)
                {
                    mmb = new MovieMetadataBox();
                    mmb.Read(this.m_reader);
                    if (mmb.ObjectDescriptorBox != null)
                    {
                        base.ObjectDescriptor = mmb.ObjectDescriptorBox.Contents;
                    }
                    if (mmb.UserDataBox != null)
                    {
                        base.UserData = mmb.UserDataBox.Data;
                    }
                }
                else if (boxType == BoxTypes.Free)
                {
                    FreeBox freeb = new FreeBox();
                    freeb.Read(this.m_reader);
                    FreeBoxList.Add(freeb);
                }
                else if (boxType == BoxTypes.MediaData) // mdat
                {
                    MediaDataBox mdb = new MediaDataBox();
                    mdb.Read(this.m_reader); // this doesn't really read all of mdat: payload is skipped
                    MediaDataBoxList.Add(mdb);
                }
                else if (boxType == BoxTypes.MovieFragmentRandomAccess)
                {
                    MovieFragmentRandomAccessBox = new MovieFragmentRandomAccessBox();
                    MovieFragmentRandomAccessBox.Read(this.m_reader);
                }
                else if (boxType == BoxTypes.Free)
                {
                    FreeBox freeBox = new FreeBox();
                    freeBox.Read(this.m_reader);
                    FreeBoxList.Add(freeBox);
                }
                else
                {
                    // invalid box, just stop reading
                    break;
                    //Box box2 = new Box(boxType);
                    //box2.Read(this.m_reader);
                    //FreeBoxList.Add(box2);
                    //Debug.WriteLine(string.Format("Unknown BoxType: {0}", box2.Type.ToString()));
                }
            } // end of while

            // now that we know all about the input file in memory... fill a few structures to help others gain access to this information...
            // this is for the case in which the mp4 file contains moov boxes (MovieMetadataBoxes).
            if ((mmb != null) && (MediaTracks.Count == 0))
            {
                DurationIn100NanoSecs = (ulong)TimeArithmetic.ConvertToStandardUnit(mmb.MovieHeaderBox.TimeScale, mmb.MovieHeaderBox.Duration);
                Hints.StreamTimeScale = mmb.MovieHeaderBox.TimeScale;
                if (!IsMediaStreamFragmented)
                {
                    CreateTracks <GenericAudioTrack, MP4VideoTrack, MP4TrackFormat>();
                }
            }
        } // end of Read method