Example #1
0
        /// <summary>
        /// Initialized the demux for given stream. After calling this you can
        /// query A/V stream info and create decoders to play back those streams.
        /// </summary>
        /// <param name="sourceStream">Source stream.</param>
        /// <param name="loadOptions">Load options.</param>
        public override void Init(Stream sourceStream, LoadOptions loadOptions = null)
        {
            var watch = new System.Diagnostics.Stopwatch();

            watch.Start();

            reader = new AtomicBinaryReader(sourceStream);

            var riffParser = new RiffParser(reader);

            avi = new AVIFile();

            idx1EntryOffset = -1;
            idx1Offset      = -1;
            currentStrh4CC  = 0;
            while (riffParser.ReadNext(ProcessAviChunk, ProcessAviList, ProcessAviRiff))
            {
                ;
            }

            if (avi.strhVideo != null)
            {
                videoStreamInfo              = new VideoStreamInfo();
                videoStreamInfo.codecFourCC  = avi.strhVideo.fccHandler;
                videoStreamInfo.bitsPerPixel = avi.strfVideo.biBitCount;
                videoStreamInfo.frameCount   = avi.odml != null ? (int)avi.odml.dwTotalFrames : (int)avi.avih.dwTotalFrames;
                videoStreamInfo.width        = (int)avi.avih.dwWidth;
                videoStreamInfo.height       = (int)avi.avih.dwHeight;
                videoStreamInfo.framerate    = (float)avi.strhVideo.dwRate / (float)avi.strhVideo.dwScale;
            }
            else
            {
                videoStreamInfo = null;
            }
            if (avi.strhAudio != null)
            {
                audioStreamInfo             = new AudioStreamInfo();
                audioStreamInfo.codecFourCC = avi.strhAudio.fccHandler;
                audioStreamInfo.audioFormat = avi.strfAudio.wFormatTag;
                audioStreamInfo.sampleCount = (int)avi.strhAudio.dwLength;
                audioStreamInfo.sampleSize  = (int)avi.strhAudio.dwSampleSize;
                audioStreamInfo.channels    = (int)avi.strfAudio.nChannels;
                audioStreamInfo.sampleRate  = (int)avi.strfAudio.nSamplesPerSec;
            }
            else
            {
                audioStreamInfo = null;
            }

            // we may already have indexes here. it happens when the AVI contained OpenDML indx elements.
            // if we don't have indexes yet, then try to parse then out from an old idx1 chunk.
            if (hasVideo)
            {
                if (avi.videoIndex == null)
                {
                    avi.videoIndex = ParseOldIndex(idx1Offset, riffParser.reader, idx1Size, AviDemux.ID_00dc, idx1EntryOffset);
                }
                if (avi.videoIndex == null)
                {
                    // currently we're just throwing an exception here, but we could also rebuild the index. It's slow, but doable.
                    throw new MpException("No video index found (required for playback and seeking)");
                }
                PrepareVideoStream();
            }
            if (hasAudio)
            {
                if (avi.audioIndex == null)
                {
                    avi.audioIndex = ParseOldIndex(idx1Offset, riffParser.reader, idx1Size, AviDemux.ID_01wb, idx1EntryOffset);
                }
                if (avi.audioIndex == null)
                {
                    // currently we're just throwing an exception here, but we could also rebuild the index. It's slow, but doable.
                    throw new MpException("No audio index found (required for playback and seeking)");
                }
                PrepareAudioStream();
            }

            // if not all the frames are indexed, fix it
            if (videoStreamInfo != null && avi.videoIndex != null && videoStreamInfo.frameCount > avi.videoIndex.entries.Count)
            {
                                #if MP_DEBUG
                Debug.LogWarning("Not all video frames are indexed. Adjusting video length to match indexed frame count " +
                                 avi.videoIndex.entries.Count + ". AVI header told that there should be " +
                                 videoStreamInfo.frameCount + " frames." + " It's likely that your encoder has a bug.");
                                #endif
                videoStreamInfo.frameCount = avi.videoIndex.entries.Count;
            }

            watch.Stop();
                        #if MP_DEBUG
            Debug.Log("AVI loaded in " + (watch.Elapsed.TotalMilliseconds * 0.001f) + " seconds");
                        #endif

            nextVideoFrame  = 0;
            nextAudioSample = 0;
        }