Example #1
0
        private void FillBuffer()
        {
            // load the indices from the database
            indexCount   = 0;
            currentIndex = 0;
            bool continuousData;

            bool streamOutOfData = DatabaseUtility.LoadIndices(indices, endingTick + 1, streamID, frame.Buffer.Length,
                                                               out indexCount, out minOffset, out maxOffset, out continuousData);

            //Debug.WriteLine("FillBuffer for StreamID=" + streamID.ToString() + "; starting tick=" + (endingTick + 1).ToString());

            // load the associated buffer from the database if we're not empty....
            if (indexCount > 0)
            {
                /// Note on data quirks: Sometimes the raw data from the archive service is out of order.
                /// I think this is a bug in Archive Service.  The indices are in order by timestamp, but the start/end fields may not
                /// align one after another.  In this case there are also corresponding discontinuities in the raw data.
                /// To work around this we have LoadIndices keep track of the minimum start and the maximum end in the
                /// indices we've just fetched.  They are not necessarily the first and last items in the array.
                /// We also add a check to make sure we don't try to fetch more data than the frame buffer can
                /// hold.

                if (!continuousData)
                {
                    DateTime dt = new DateTime(this.endingTick + 1);
                    Console.WriteLine("DBStreamPlayer.FillBuffer: A data discontinuity was found for streamID=" + streamID.ToString() + ";near time=" + dt.ToString());
                }

                this.startingTick = indices[0].timestamp;
                this.endingTick   = indices[indexCount - 1].timestamp;

                DatabaseUtility.LoadBuffer(streamID, minOffset, maxOffset, ref frame);
            }
            else
            {
                streamEndReached = true;
            }
        }
        /// <summary>
        /// Return true if the database contains no data for the given payload/cname/name/timerange.
        /// if name is null or empty, exclude it from the where clause.
        /// </summary>
        public static bool isEmptyStream(PayloadType payload, String cname, String name, long start, long end)
        {
            String query = "select count(*) " +
                           "from participant p join stream s on p.participant_id=s.participant_id " +
                           "join frame f on s.stream_id=f.stream_id where s.payload_type='" +
                           payload.ToString() + "' and p.cname='" + cname + "' ";

            if ((name != null) && (name.Trim() != ""))
            {
                query += "and s.name='" + name + "' ";
            }

            query += "and f.frame_time >= " + start.ToString() + " and f.frame_time < " +
                     end.ToString();

            int count = DatabaseUtility.numericQuery(query);

            if (count == 0)
            {
                return(true);
            }
            return(false);
        }
        /// <summary>
        /// Submit a query to return a single Int32
        /// </summary>
        /// <returns></returns>
        private static int numericQuery(String query)
        {
            if (!DatabaseUtility.openAndExecute(query))
            {
                return(-1);
            }

            int count = -1;

            try
            {
                if (reader.Read())
                {
                    count = reader.GetInt32(0);
                }
            }
            finally
            {
                DatabaseUtility.cleanUpConnection();
            }

            return(count);
        }
        public static long GetConferenceStartTime(PayloadType payload, String cname, long start, long end)
        {
            String query = "select c.start_dttm " +
                           "from conference c " +
                           "join participant p on c.conference_id=p.conference_id " +
                           "join stream s on p.participant_id=s.participant_id " +
                           "join frame f on s.stream_id=f.stream_id " +
                           "where s.payload_type='" + payload.ToString() + "' " +
                           "and p.cname='" + cname + "' " +
                           "and f.frame_time > " + start.ToString() + " " +
                           "and f.frame_time < " + end.ToString() + " " +
                           "group by c.start_dttm";

            //Debug.WriteLine(query);

            if (!DatabaseUtility.openAndExecute(query))
            {
                return(0);
            }

            long ret = 0;

            try
            {
                if (reader.Read())
                {
                    DateTime dt = reader.GetDateTime(0);
                    ret = dt.Ticks;
                }
            }
            finally
            {
                DatabaseUtility.cleanUpConnection();
            }

            return(ret);
        }
        /// <summary>
        /// Return the first frame for the given stream.
        /// </summary>
        /// <param name="streamID"></param>
        /// <returns></returns>
        public static byte[] GetFirstFrame(int streamID)
        {
            String query = "select top 1 f.raw_start, f.raw_end " +
                           "from stream s join frame f on s.stream_id=f.stream_id " +
                           "where s.stream_id=" + streamID.ToString() + " " +
                           "order by f.frame_time ";

            if (!DatabaseUtility.openAndExecute(query))
            {
                return(null);
            }

            int raw_start = -1;
            int raw_end   = -1;

            try
            {
                if (reader.Read())
                {
                    raw_start = reader.GetInt32(0);
                    raw_end   = reader.GetInt32(1);
                }
            }
            finally
            {
                DatabaseUtility.cleanUpConnection();
            }

            if (raw_start != -1)
            {
                BufferChunk ret = new BufferChunk(raw_end - raw_start + 1);
                LoadBuffer(streamID, raw_start, raw_end, ref ret);
                return(ret.Buffer);
            }
            return(null);
        }
        /// <summary>
        /// Like get streams, but doesn't return the frame count.  It turns out that is the expensive part of the query.
        /// Consequently this can run a bit faster.
        /// </summary>
        public static Stream[] GetStreamsFaster(int participantID)
        {
            String query = "SELECT	s.stream_id, s.name, s.payload_type, "+
                           "( SELECT (MAX( frame_time ) - MIN(frame_time))/10000000 " +
                           "FROM frame WHERE stream_id = s.stream_id ) as seconds, " +
                           "( SELECT datalength(data) FROM rawStream WHERE stream_id =  s.stream_id) as bytes " +
                           "FROM stream as s WHERE s.participant_id = " + participantID.ToString() +
                           " AND (SELECT datalength(data) FROM rawStream WHERE stream_id =  s.stream_id) > 1 " +
                           "ORDER BY [name] ASC";

            if (!DatabaseUtility.openAndExecute(query))
            {
                return(null);
            }

            ArrayList al = new ArrayList();

            try {
                while (reader.Read())
                {
                    Stream stream = new Stream(
                        reader.GetInt32(0),                           //stream id
                        reader.GetString(1),                          // name
                        reader.GetString(2),                          // payload,
                        1000,                                         // frames
                        reader.IsDBNull(3) ? 0L : reader.GetInt64(3), // seconds
                        reader.GetInt32(4));                          // bytes
                    al.Add(stream);
                }
            }
            finally {
                DatabaseUtility.cleanUpConnection();
            }

            return((Stream[])al.ToArray(typeof(Stream)));
        }
        /// <summary>
        /// Thread proc to examine presentation data to find referenced slide decks.
        /// </summary>
        private void AnalyzeThread()
        {
            decks.Clear();
            this.unnamedDecks = new Hashtable();
            BufferChunk frame;
            long        timestamp;

            progressTracker = new ProgressTracker(1);
            progressTracker.CustomMessage   = "Initializing";
            progressTracker.CurrentValue    = 0;
            progressTracker.EndValue        = 100;    //dummy value to start with.
            progressTracker.OnShowProgress += new ProgressTracker.showProgressCallback(OnShowProgress);
            progressTracker.Start();

            //Note: there would be multiple streams here if the presenter left the venue and rejoined during the segment.
            // This is in the context of a single segment, so we can assume one cname, and no overlapping streams.
            int[] streams = DatabaseUtility.GetStreams(payload, cname, null, dtstart.Ticks, dtend.Ticks);
            if (streams == null)
            {
                progressTracker.Stop();
                progressTracker = null;
                this.OnAnalyzeCompleted();
                return;
            }

            DBStreamPlayer[] streamPlayers = new DBStreamPlayer[streams.Length];
            double           totalDuration = 0;

            for (int i = 0; i < streams.Length; i++)
            {
                streamPlayers[i] = new DBStreamPlayer(streams[i], dtstart.Ticks, dtend.Ticks, this.payload);
                totalDuration   += ((TimeSpan)(streamPlayers[i].End - streamPlayers[i].Start)).TotalSeconds;
            }

            progressTracker.EndValue      = (int)totalDuration;
            progressTracker.CustomMessage = "Analyzing";

            int framecount = 0;

            for (int i = 0; i < streamPlayers.Length; i++)
            {
                if (stopAnalyze)
                {
                    break;
                }
                while ((streamPlayers[i].GetNextFrame(out frame, out timestamp)))
                {
                    if (stopAnalyze)
                    {
                        break;
                    }
                    ProcessFrame(frame);
                    progressTracker.CurrentValue = (int)(((TimeSpan)(new DateTime(timestamp) - streamPlayers[0].Start)).TotalSeconds);
                    framecount++;
                }
            }

            if ((!stopAnalyze) && (this.OnAnalyzeCompleted != null))
            {
                mergeUnnamedDecks();
                progressTracker.Stop();
                progressTracker = null;
                this.OnAnalyzeCompleted();
            }
        }
        private void lookupThreadProc()
        {
            working.Reset();

            if (!DatabaseUtility.CheckConnectivity())
            {
                done            = true;
                sqlConnectError = true;
                working.Set();
                return;
            }

            Conference[] confs = DatabaseUtility.GetConferences();
            this.conferenceData = new ArrayList();

            participantCount = DatabaseUtility.CountParticipants();
            if (participantCount < 1)
            {
                done            = true;
                sqlConnectError = false;
                working.Set();
                return;
            }

            currentParticipant = 0;

            foreach (Conference c in confs)
            {
                if (stopNow)
                {
                    break;
                }
                ConferenceWrapper cw = new ConferenceWrapper();
                cw.Conference   = c;
                cw.Description  = "Conference: " + c.Start.ToString() + " - " + c.Description;
                cw.Participants = new ArrayList();

                Participant[] participants = DatabaseUtility.GetParticipants(c.ConferenceID);
                foreach (Participant part in participants)
                {
                    if (stopNow)
                    {
                        break;
                    }
                    ParticipantWrapper pw = new ParticipantWrapper();

                    pw.Description   = "Participant: " + part.CName;
                    pw.Participant   = part;
                    pw.StreamGrouper = new StreamGrouper(part.CName);

                    //Here is the slow part:
                    Stream[] streams = DatabaseUtility.GetStreams(part.ParticipantID);
                    currentParticipant++;

                    if (streams == null)
                    {
                        continue;
                    }

                    foreach (Stream str in streams)
                    {
                        pw.StreamGrouper.AddStream(str);
                    }

                    //Only show the participants that sent some supported data
                    if (pw.StreamGrouper.GroupCount > 0)
                    {
                        cw.Participants.Add(pw);
                    }
                }

                conferenceData.Add(cw);
            }
            done = true;
            working.Set();
        }
        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;
            }
        }