public int GetNumFramesInVideo() { //return m_sampleCount; // TODO: Get Brad to fix this. Get Video properties returns wrong number of frames in video GopRecord gop = m_gopList[m_gopList.Keys.Max()]; int num = gop.frameIndex; return(num); }
public bool GetGopList(string mp4Filename, SortedList <int, GopRecord> gopList) { bool success = true; if (gopList == null) { gopList = m_gopList; } gopList.Clear(); m_gopIndexLookup.Clear(); if (m_mp4Reader != IntPtr.Zero) { double[] timestamps; Mp4.GetVideoKeyFrameTimestamps(m_mp4Reader, out timestamps); int[] framesInGop = new int[timestamps.Length]; // FIX Mp4.GetVideoGOPLengths(m_mp4Reader, out framesInGop); int ndx = 0; for (int i = 0; i < timestamps.Length; i++) { gopList.Add(i, new GopRecord(ndx, timestamps[i], framesInGop[i])); m_gopIndexLookup.Add(timestamps[i], ndx); ndx += framesInGop[i]; } } else { success = false; } if (gopList.Count > 0) { GopRecord gop = gopList[gopList.Keys.Max()]; m_maxFrameIndex = gop.frameIndex + gop.numFrames - 1; } else { m_maxFrameIndex = 0; } return(success); }
public ITargetBlock <Tuple <int> > CreateCacheUpdatePipeline(int padding) { SortedList <int, GopRecord> l_gopList = new SortedList <int, GopRecord>(); SortedList <int, FrameRecord> l_frameCache = new SortedList <int, FrameRecord>(); List <int> l_gopsLoaded = new List <int>(); int l_padding = padding; int l_currentGOP = -1; FrameRecord frame; // initialize cache bool success1 = true; if (GetGopList(m_mp4Filename, l_gopList)) { for (int i = 0; i < padding + 1; i++) { if (LoadGopIntoCache(i, l_gopList, l_frameCache)) { l_gopsLoaded.Add(i); } else { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.ERROR, "Error Intializing Cache", null)); success1 = false; break; } } } else { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.ERROR, "Error Intializing GOP List", null)); success1 = false; } // send first image in file if (success1) { l_currentGOP = 0; double timestamp; int width, height, depth; byte[] frameData; if (l_frameCache.TryGetValue(0, out frame)) { if (ReadFile(frame.filename, out timestamp, out width, out height, out depth, out frameData)) { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.FRAME, "", new FramePackage(0, timestamp, 0, 0.0, new DNNTools.ImagePackage(frameData, timestamp, width, height, depth)))); } else { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.ERROR, "Failed to read Image File from Cache: " + frame.filename, null)); } } } /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// var RequestImage = new ActionBlock <Tuple <int> >(inputData => { int frameIndex = inputData.Item1; bool success; double timestamp; int width, height, depth; byte[] frameData; if (l_frameCache.TryGetValue(frameIndex, out frame)) { success = ReadFile(frame.filename, out timestamp, out width, out height, out depth, out frameData); if (success) { GopRecord gop = m_gopList[l_currentGOP]; OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.FRAME, "", new FramePackage(frameIndex, timestamp, l_currentGOP, gop.timestamp, new DNNTools.ImagePackage(frameData, timestamp, width, height, depth)))); } else { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.ERROR, "Failed to read Image File from Cache: " + frame.filename, null)); } } else { // figure out which GOPs to load int gopToLoad = GetGopIndexContainingFrameIndex(frameIndex, l_gopList); if (gopToLoad != -1) // if gop found, -1 indicates that it wasn't found { if (LoadGopIntoCache(gopToLoad, l_gopList, l_frameCache)) { l_gopsLoaded.Add(gopToLoad); l_gopsLoaded.Sort(); if (l_frameCache.TryGetValue(frameIndex, out frame)) { if (ReadFile(frame.filename, out timestamp, out width, out height, out depth, out frameData)) { l_currentGOP = gopToLoad; GopRecord gop = m_gopList[l_currentGOP]; OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.FRAME, "", new FramePackage(frameIndex, timestamp, l_currentGOP, gop.timestamp, new DNNTools.ImagePackage(frameData, timestamp, width, height, depth)))); } else { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.ERROR, "Failed to read Image File from Cache: " + frame.filename + "\nafter trying to load GOP into Cache.", null)); } } // check to see if cache has grown to be too large. If so, remove a gop from cache if (l_gopsLoaded.Count > (2 * l_padding + 1)) { int lowestGop = l_gopsLoaded[0]; int highestGop = l_gopsLoaded[l_gopsLoaded.Count - 1]; int interval1 = Math.Abs(l_currentGOP - lowestGop); int interval2 = Math.Abs(highestGop - l_currentGOP); if (interval1 > interval2) { if (RemoveGopFromCache(lowestGop, l_gopList, l_frameCache)) { l_gopsLoaded.RemoveAt(0); } } else { if (RemoveGopFromCache(highestGop, l_gopList, l_frameCache)) { l_gopsLoaded.RemoveAt(l_gopsLoaded.Count - 1); } } } } else { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.ERROR, "Failed to Load GOP " + gopToLoad.ToString(), null)); } } else { OnVideoCacheEvent(new VideoCache_EventArgs(VideoCache_Status_Type.REACHED_END_OF_FILE, "Reached EOF", null)); } } }); return(RequestImage); }