Exemplo n.º 1
0
        /// <summary>
        /// AdjustTrackSpecsToDestination
        /// The purpose of this is to control the recoding by modifying two instances of the class
        /// BaseTrackInfo under the two subclasses RawAudioTrackInfo and RawVideoTrackInfo.
        /// By default, these subclass instances take on the characteristics of the input media.
        /// NOTE: This method should be XML driven or should pick up parameters from a configuration file.
        /// FIXME: What about other track types?
        /// </summary>
        protected void AdjustTrackSpecsToDestination()
        {
            foreach (IsochronousTrackInfo trackDef in TrackInfo)
            {
                trackDef.TrackID = 0; // reset track ID (destination stream should determine track ID)
                if (trackDef is RawVideoTrackInfo)
                {
                    trackDef.CTTSOut = CTTSOut;
                }
            }

            uint oneSecondTicks = (uint)TimeSpan.TicksPerSecond;

            if (DestStream.GetType().FullName.Equals("Media.Formats.MP4.MP4StreamWriter"))
            {
                TrackInfo.ForEach(delegate(IsochronousTrackInfo trk)
                {
                    // set the movie time scale to 1,000
                    trk.MovieTimeScale = 1000;

                    // Set the track time scale to 10,000.
                    // QuickTime cannot handle ulong durations, and our mp4 writer automatically switches to ulong if
                    // a movie is more than 2,166,748,000 units long (a value which goes beyond int.MaxValue).
                    // The track duration can get this high if the time scale is 10,000,000 which is what Expression uses.
                    trk.TimeScale = 10000;

                    if (trk is RawVideoTrackInfo)
                    {
                        trk.CTTSOut = CTTSOut;
                    }
                    else if (trk is RawAudioTrackInfo)
                    {
                        // if we are recoding to MP4 from HyperAsset, private codec data should be set as follows
                        if (SourceStream.GetType().FullName.Contains(".AssetMediaStream")) // This needs to encompass the new AssetMediaStream2 class.
                        {
                            trk.CodecPrivateData = "038080220000000480801640150020000001F4000001F4000580800511900000000680800102";
                        }
                    }
                });
            }
            else if (DestStream.IsMediaStreamFragmented)
            {
                TrackInfo.ForEach(delegate(IsochronousTrackInfo trk)
                {
                    if (trk is RawVideoTrackInfo)
                    {
                        // modify RawVideoTrackInfo: for fragmented tracks, timescale should be = oneSecondTicks
                        // rvti.MovieDurationIn100NanoSecs = rvti.MovieDurationIn100NanoSecs * (oneSecondTicks / rvti.MovieTimeScale); // FIXME: what if rvti.MovieTimeScale > oneSecondTicks ticks?
                        trk.MovieTimeScale = oneSecondTicks;
                        //rvti.DurationIn100NanoSecs = rvti.DurationIn100NanoSecs * (oneSecondTicks / rvti.TimeScale);
                        trk.TimeScale = oneSecondTicks;

                        trk.IsFragment = true;
                    }
                });
            }

            if (TrackInfo.Any(t => t is RawAudioTrackInfo))
            {
                RawAudioTrackInfo rati = (RawAudioTrackInfo)TrackInfo.First(t => t is RawAudioTrackInfo);
                if ((rati != null) && (audioOrVideoOrBoth == TracksIncluded.Video))
                {
                    TrackInfo.Remove(rati);
                    rati = null;
                }
            }

            if (audioOrVideoOrBoth == TracksIncluded.Audio)
            {
                IsochronousTrackInfo rvti;
                do
                {
                    rvti = TrackInfo.FirstOrDefault(t => t is RawVideoTrackInfo);
                    if (rvti != null)
                    {
                        TrackInfo.Remove(rvti);
                    }
                } while (rvti != null);
            }
        }