internal bool SaveAsAviFile(string fileName, int firstFrame, int lastFrame, AdvToAviConverter converter, bool tryCodec, bool isCalibrationStream, double msPerFrame, double addedGamma, OnProgressDelegate progressCallback) { IAviSaver saver = AdvToAviConverterFactory.CreateConverter(converter); saver.CloseAviFile(); if (!saver.StartNewAviFile(fileName, (int)m_AdvFile.Width, (int)m_AdvFile.Height, 8, 25, tryCodec)) { progressCallback(100, 0); return(false); } try { int aviFrameNo = 0; AdvIndexEntry firstFrameIdx = isCalibrationStream ? m_AdvFile.CalibrationIndex[firstFrame] : m_AdvFile.MainIndex[firstFrame]; double ticksToMSFactor = 1000.0 / (isCalibrationStream ? m_AdvFile.CalibrationSteamInfo.ClockFrequency : m_AdvFile.MainSteamInfo.ClockFrequency); double startingTimeMilliseconds = firstFrameIdx.ElapsedTicks * ticksToMSFactor; if (m_AdvFile.MainIndex[lastFrame].ElapsedTicks != 0) { // Sampling can be done as we have sufficient timing information } else { InvokeMessageBox( "There is insufficient timing information in this file to convert it to AVI. This could be caused by an old file format or trying to make an AVI from a single frame.", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } if (InvokeMessageBox( "Please note that the AVI export is doing resampling of the original video which will typically cause frames to duplicated and/or dropped.\r\n\r\nThis export function is meant to be used for video streaming (i.e. sharing the video for viewing on the Internet) and should not be used to convert the video to another format for measuring in another software. If you want to measure the video in another software either measure it directly as ADV/AAV file (if supported) or export it to a FITS file sequence from the main file menu and measure the FITS images.\r\n\r\nDo you wish to continue?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) != DialogResult.Yes) { return(false); } progressCallback(5, 0); for (int i = firstFrame; i <= lastFrame; i++) { AdvIndexEntry frame = isCalibrationStream ? m_AdvFile.CalibrationIndex[i] : m_AdvFile.MainIndex[i]; AdvFrameInfo frameInfo = null; uint[] pixels = null; if (isCalibrationStream) { pixels = m_AdvFile.GetCalibrationFramePixels((uint)i, out frameInfo); } else { pixels = m_AdvFile.GetMainFramePixels((uint)i, out frameInfo); } using (Pixelmap pixmap = CreatePixelmap(pixels)) { int lastRepeatedAviFrameNo = 0; if (frame.ElapsedTicks != 0) { lastRepeatedAviFrameNo = (int)Math.Round((frame.ElapsedTicks * ticksToMSFactor - startingTimeMilliseconds) / msPerFrame); } while (aviFrameNo < lastRepeatedAviFrameNo) { if (!saver.AddAviVideoFrame(pixmap, addedGamma, m_AdvFile.MaxPixelValue)) { progressCallback(100, 0); return(false); } aviFrameNo++; } } int percDone = (int)Math.Min(90, 90 * (i - firstFrame) * 1.0 / (lastFrame - firstFrame + 1)); progressCallback(5 + percDone, 0); } } finally { saver.CloseAviFile(); progressCallback(100, 0); } return(false); }
internal bool SaveAsAviFile(string fileName, int firstFrame, int lastFrame, AdvToAviConverter converter, bool tryCodec, double msPerFrame, double addedGamma, OnSearchProgressDelegate progressCallback) { IAviSaver saver = AdvToAviConverterFactory.CreateConverter(converter); saver.CloseAviFile(); if (!saver.StartNewAviFile(fileName, (int)ImageSection.Width, (int)ImageSection.Height, 8, 25, tryCodec)) { progressCallback(100, 0); return(false); } try { int aviFrameNo = 0; AdvFramesIndexEntry firstFrameIdx = m_Index.Index[firstFrame]; double startingTimeMilliseconds = firstFrameIdx.ElapsedTime.TotalMilliseconds; bool isAavFile = AdvFileTags["FSTF-TYPE"] == "AAV"; double effFrameDuration = double.NaN; try { effFrameDuration = 1000 / double.Parse(AdvFileTags["EFFECTIVE-FRAME-RATE"]); } catch { } if (isAavFile && m_Index.Index[lastFrame].ElapsedTime.Ticks == 0 && (double.IsNaN(effFrameDuration) || double.IsInfinity(effFrameDuration))) { MessageBox.Show( "This AAV video format is too old or the AAV file is corrupted. It cannot be converted to AVI", "Tangra 3", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } if ((isAavFile && !double.IsNaN(effFrameDuration)) || !isAavFile && m_Index.Index[lastFrame].ElapsedTime.Ticks != 0) { // Sampling can be done as we have sufficient timing information } else { MessageBox.Show( "There is insufficient timing information in this file to convert it to AVI. This could be caused by an old file format.", "Tangra 3", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } progressCallback(5, 0); for (int i = firstFrame; i <= lastFrame; i++) { AdvFramesIndexEntry frame = m_Index.Index[i]; AdvImageData currentImageData; AdvStatusData currentStatusData; Bitmap currentBitmap; using (Pixelmap pixmap = GetFrameData(i, out currentImageData, out currentStatusData, out currentBitmap)) { int lastRepeatedAviFrameNo = 0; if (isAavFile && !double.IsNaN(effFrameDuration)) { lastRepeatedAviFrameNo = (int)Math.Round(((i - firstFrame) * effFrameDuration) / msPerFrame); } else if (!isAavFile && frame.ElapsedTime.Ticks != 0) { lastRepeatedAviFrameNo = (int)Math.Round((frame.ElapsedTime.TotalMilliseconds - startingTimeMilliseconds) / msPerFrame); } while (aviFrameNo < lastRepeatedAviFrameNo) { if (!saver.AddAviVideoFrame(pixmap, addedGamma, ImageSection.Adv16NormalisationValue)) { progressCallback(100, 0); return(false); } aviFrameNo++; } if (currentBitmap != null) { currentBitmap.Dispose(); } } int percDone = (int)Math.Min(90, 90 * (i - firstFrame) * 1.0 / (lastFrame - firstFrame + 1)); progressCallback(5 + percDone, 0); } } finally { saver.CloseAviFile(); progressCallback(100, 0); } return(false); }