Exemplo n.º 1
0
        /// <summary>
        /// Make sure all the streams for this StreamMgr have compatible compressed media types.
        /// Also check against the media type, optionally supplied as an argument.
        /// Log details about any problems we find.
        /// </summary>
        /// In no-recompression scenarios including the preview we check this and warn the user,
        /// though we can't do anything about it.
        /// <param name="prevMT">An additional MediaType to check against, or null if none</param>
        /// <param name="log">Where to write details about any problems found</param>
        /// <returns>always true</returns>
        public bool ValidateCompressedMT(MediaType prevMT, LogMgr log)
        {
            MediaType lastMT = prevMT;

            for (int i = 0; i < streamPlayers.Length; i++)
            {
                if (payload == PayloadType.dynamicVideo)
                {
                    if (!ProfileUtility.CompareVideoMediaTypes((MediaTypeVideoInfo)streamPlayers[i].StreamMediaType, (MediaTypeVideoInfo)lastMT))
                    {
                        Debug.WriteLine("incompatible video mediatype found.");
                        log.WriteLine("Warning: A change in the media type was found in the video stream from " + this.cname +
                                      " beginning at " + streamPlayers[i].Start.ToString() + ".  Without recompression, this may cause " +
                                      " a problem with the output.  Using recompression should resolve the issue. ");
                        log.ErrorLevel = 5;
                    }
                }
                else if (payload == PayloadType.dynamicAudio)
                {
                    if (!ProfileUtility.CompareAudioMediaTypes((MediaTypeWaveFormatEx)streamPlayers[i].StreamMediaType, (MediaTypeWaveFormatEx)lastMT))
                    {
                        Debug.WriteLine("incompatible mediatype found.");
                        log.WriteLine("Warning: A change in the media type was found in the audio stream from " + this.cname +
                                      " beginning at " + streamPlayers[i].Start.ToString() + ".  Without recompression, this may cause " +
                                      " a problem with the output.  Using recompression should resolve the issue. ");
                        log.ErrorLevel = 5;
                    }
                }
                lastMT = streamPlayers[i].StreamMediaType;
            }
            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Assume that all the StreamMgrs provided are configured with the correct time range. Do not assume
        /// contiguous data, or compatible media types.
        /// </summary>
        /// <param name="audioMgr"></param>
        /// <param name="log"></param>
        public AudioMixer(StreamMgr[] audioMgr, LogMgr log)
        {
            fileStreamPlayer = null;
            this.audioMgr    = audioMgr;
            this.log         = log;
            refTime          = long.MinValue;
            inbufs           = new ArrayList();

            if (audioMgr.Length == 0)
            {
                return;
            }


            /// Examine the uncompressed MT's for each audioMgr, and implement a voting system so that the
            /// media type that is dominant for this mixer is the one we use, and other incompatible MT's
            /// are ignored in the mix.  Log a warning at places where the MT changes.
            /// Remember that each audioMgr may itself have multiple FileStreamPlayers which have different uncompressed
            /// media types.
            /// Finally we need to make our uncompressed MT available to the caller for use in configuring the writer.
            /// Later on let's look at ways to convert any common uncompressed types so that they are compatible.
            AudioCompatibilityMgr audioCompatibilityMgr = new AudioCompatibilityMgr();

            foreach (StreamMgr astream in audioMgr)
            {
                astream.CheckUncompressedAudioTypes(audioCompatibilityMgr);
            }

            this.uncompressedMediaType = audioCompatibilityMgr.GetDominantType();
            String warning = audioCompatibilityMgr.GetWarningString();

            if (warning != "")
            {
                log.WriteLine(warning);
                log.ErrorLevel = 5;
            }
            incompatibleGuids = audioCompatibilityMgr.GetIncompatibleGuids();

            // Here we also want to collect a "native" (compressed) profile corresponding to one of the "compatible"
            // streams.  This is useful in case we need to recompress.  Note this profile can be created if we have
            // a stream ID.
            compatibleStreamID = audioCompatibilityMgr.GetCompatibleStreamID();

            this.bitsPerSample  = this.uncompressedMediaType.WaveFormatEx.BitsPerSample;
            this.bytesPerSample = bitsPerSample / 8;
            this.ticksPerSample = ((uint)Constants.TicksPerSec) / (this.uncompressedMediaType.WaveFormatEx.SamplesPerSec * this.uncompressedMediaType.WaveFormatEx.Channels);
            limit = (long)((ulong)1 << (int)bitsPerSample) / 2 - 1;             //clip level

            buffers = new SampleBuffer[audioMgr.Length];
            for (int i = 0; i < buffers.Length; i++)
            {
                buffers[i] = new SampleBuffer(audioMgr[i], ticksPerSample, incompatibleGuids, this.uncompressedMediaType.WaveFormatEx.Channels);
            }
        }
        public SlideStreamMgr(ArchiveTranscoderJob job, ArchiveTranscoderJobSegment segment,
                              LogMgr logMgr, double fps, int width, int height)
        {
            this.job     = job;
            this.segment = segment;
            this.logMgr  = logMgr;

            if (width > 0 && height > 0)
            {
                this.outputWidth  = width;
                this.outputHeight = height;
            }

            this.ticksBetweenFrames = (long)((double)Constants.TicksPerSec / fps);

            uncompressedMT = getUncompressedMT(this.outputWidth, this.outputHeight, fps);
            cancel         = false;
            initialized    = false;
            pptInstalled   = Utility.CheckPptIsInstalled();

            if ((!DateTime.TryParse(segment.StartTime, out start)) ||
                (!DateTime.TryParse(segment.EndTime, out end)))
            {
                throw(new System.Exception("Failed to parse start/end time"));
            }

            this.nextFrameTime = start.Ticks;

            format  = Utility.StringToPresenterWireFormatType(segment.PresentationDescriptor.PresentationFormat);
            payload = Utility.formatToPayload(format);
            cname   = segment.PresentationDescriptor.PresentationCname;

            slideImageMgr = new SlideImageMgr(format, this.outputWidth, this.outputHeight);

            //Get the start time for the entire conference and use that to get streams.
            long confStart = DatabaseUtility.GetConferenceStartTime(payload, cname, start.Ticks, end.Ticks);

            if (confStart <= 0)
            {
                logMgr.WriteLine("Warning: No conference exists in the database that matches this presentation: " + cname +
                                 " with PresentationFormat " + format.ToString());
                logMgr.ErrorLevel = 7;
                confStart         = start.Ticks;
            }

            //Get the relevant stream_id's and create DBStreamPlayers for each.
            streamIDs = DatabaseUtility.GetStreams(payload, segment.PresentationDescriptor.PresentationCname, null, confStart, end.Ticks);
            DateTime sdt = new DateTime(confStart);

            Debug.WriteLine("***Conference start: " + sdt.ToString() + " end: " + end.ToString());
            if ((streamIDs == null) || (streamIDs.Length == 0))
            {
                Debug.WriteLine("No presentation data found.");
                logMgr.WriteLine("Warning: No presentation data was found for the given time range for " +
                                 cname + " with PresentationFormat " + format.ToString());
                logMgr.ErrorLevel = 7;
                streamPlayers     = null;
                return;
            }

            streamPlayers = new DBStreamPlayer[streamIDs.Length];
            for (int i = 0; i < streamIDs.Length; i++)
            {
                streamPlayers[i] = new DBStreamPlayer(streamIDs[i], confStart, end.Ticks, payload);
            }

            lookBehindDuration = 0;
            if (streamPlayers[0].Start < start)
            {
                lookBehindDuration = ((TimeSpan)(start - streamPlayers[0].Start)).TotalSeconds;
            }
        }
        /// <summary>
        /// Build a list of slide decks referenced in the job, and generate a directory of slide images for each deck.
        /// </summary>
        public void Process()
        {
            progressTracker.CustomMessage = "Processing Slides";
            progressTracker.CurrentValue  = 0;

            //build a list of decks from the job spec
            Hashtable workList = new Hashtable();

            log.WriteLine("Generating Slide Images.");
            foreach (ArchiveTranscoderJobSegment segment in job.Segment)
            {
                if (segment.SlideDecks != null)
                {
                    foreach (ArchiveTranscoderJobSlideDeck deck in segment.SlideDecks)
                    {
                        Guid deckGuid = new Guid(deck.DeckGuid);
                        if (this.outputDirs.ContainsKey(deckGuid))
                        {
                            //Deck was previously converted.
                            continue;
                        }

                        if (!workList.ContainsKey(deckGuid))
                        {
                            if (deck.Path == null)
                            {
                                //unmatched deck
                                log.WriteLine("Warning: Specified deck has not been matched to a file: " + deck.Title);
                                log.ErrorLevel = 5;
                                continue;
                            }
                            FileInfo fi = new FileInfo(deck.Path);
                            if (fi.Exists)
                            {
                                workList.Add(deckGuid, fi);
                            }
                            else
                            {
                                DirectoryInfo di = new DirectoryInfo(deck.Path);
                                if (di.Exists)
                                {
                                    workList.Add(deckGuid, di);
                                }
                                else
                                {
                                    log.WriteLine("Warning: Specified deck does not exist: " + fi.FullName);
                                    log.ErrorLevel = 5;
                                }
                            }
                        }
                        else if (deck.Path != ((FileInfo)workList[deckGuid]).FullName)
                        {
                            log.WriteLine("Warning: The same deck was specified with different paths: " +
                                          deck.Path + " " + ((FileInfo)workList[deckGuid]).FullName);
                            log.ErrorLevel = 3;
                        }
                    }
                }
            }
            log.WriteLine("Found " + workList.Count.ToString() + " deck(s) in the job.");

            //Since it is impractical to find out how many slides are in each deck here, we will consider each deck to
            //be worth 100 in progressTracker.
            int deckCount = workList.Count;

            if (rtDocuments != null)
            {
                deckCount += rtDocuments.Count;
            }
            if (slideMessages != null)
            {
                //For now we ignore these since there are assumed to be just a few at most.
            }

            progressTracker.EndValue = deckCount * 100;

            //Build image directory for each deck
            if (workList.Count > 0)
            {
                int currentDeck = 0;
                foreach (Guid g in workList.Keys)
                {
                    if (workList[g] is FileInfo)
                    {
                        if (((FileInfo)workList[g]).FullName.ToLower().IndexOf(".ppt", 1) > 0)
                        {
                            if (Utility.CheckPptIsInstalled())
                            {
                                if (this.useNativeJpegExport || this.usePPTImageExport)
                                {
                                    // Use Powerpoint directly to do the image export
                                    processPpt(g, (FileInfo)workList[g]);
                                }
                                else
                                {
                                    // Use CP3 to open the PPT file and do the export
                                    processPptWithCp3(g, (FileInfo)workList[g]);
                                }
                            }
                            else
                            {
                                log.WriteLine("Warning: A PowerPoint deck was specified, but PowerPoint does not appear to be " +
                                              "installed on this system.  This deck will be ignored: " +
                                              ((FileInfo)workList[g]).FullName + "  To resolve this problem specify a CSD deck in the job, " +
                                              "or run Archive Transcoder on a system with PowerPoint installed.");
                                log.ErrorLevel = 5;
                            }
                        }
                        else if (((FileInfo)workList[g]).FullName.ToLower().IndexOf(".csd", 1) > 0)
                        {
                            processCsd(g, (FileInfo)workList[g]);
                        }
                        else if (((FileInfo)workList[g]).FullName.ToLower().IndexOf(".cp3", 1) > 0)
                        {
                            processCp3(g, (FileInfo)workList[g]);
                        }
                        else
                        {
                            log.WriteLine("Warning: unsupported deck file type: " + ((FileInfo)workList[g]).FullName +
                                          "  This deck will be ignored.");
                            log.ErrorLevel = 5;
                        }
                    }
                    else if (workList[g] is DirectoryInfo)
                    {
                        processDir(g, (DirectoryInfo)workList[g]);
                    }
                    currentDeck++;
                }
            }

            if (pptApp != null)
            {
                if (!pptAlreadyOpen)
                {
                    try {
                        pptApp.Quit();
                    }
                    catch { }
                }
                pptApp = null;
                GC.Collect();
            }


            if ((!stopNow) && (this.rtDocuments != null))
            {
                foreach (Guid g in rtDocuments.Keys)
                {
                    processRTDocument((RTDocument)rtDocuments[g]);
                }
            }

            if ((!stopNow) && (this.slideMessages != null))
            {
                foreach (String s in slideMessages.Keys)
                {
                    processSlideMessage((WorkSpace.SlideMessage)slideMessages[s]);
                }
            }
        }