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; } }