// Process a RIFF chunk element (skip the data) public void ProcessChunk(RiffParser rp, int FourCC, int length, int paddedLength) { string type = RiffParser.FromFourCC(FourCC); Debug.WriteLine("Found chunk element of type \"" + type + "\" and length " + length.ToString()); if (type.Trim() == "fmt") { BinaryReader br = new BinaryReader(rp.m_stream); var format = br.ReadUInt16(); var channels = br.ReadUInt16(); var sampleRate = br.ReadUInt32(); var bytePerSec = br.ReadUInt32(); var blockSize = br.ReadUInt16(); var bit = br.ReadUInt16(); Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { this.Info.Text = $"{channels} channels / {sampleRate} hz / {bit} bit / {bytePerSec} bytes/sec"; }); rp.SkipData(paddedLength - 16); } else { // Skip data and update bytesleft rp.SkipData(paddedLength); } }
void DoInfoWindow(int windowID) { if (moviePlayerBase.movie != null) { var demux = moviePlayerBase.movie.demux; DrawLabelValue("Demux", demux != null ? demux.GetType().ToString() : "N/A"); if (demux != null) { if (demux.hasVideo) { var videoStreamInfo = moviePlayerBase.movie.demux.videoStreamInfo; var videoDecoder = moviePlayerBase.movie.videoDecoder; DrawLabelValue("Video fourCC", RiffParser.FromFourCC(videoStreamInfo.codecFourCC)); DrawLabelValue("Video decoder", videoDecoder != null ? videoDecoder.GetType().ToString() : "N/A"); DrawLabelValue("bitsPerPixel", videoStreamInfo.bitsPerPixel.ToString()); DrawLabelValue("frameCount", videoStreamInfo.frameCount.ToString()); DrawLabelValue("frame size", videoStreamInfo.width + "x" + videoStreamInfo.height); DrawLabelValue("framerate", videoStreamInfo.framerate.ToString()); DrawLabelValue("lengthBytes", videoStreamInfo.lengthBytes.ToString()); DrawLabelValue("lengthSeconds", videoStreamInfo.lengthSeconds.ToString()); } else { GUILayout.Label("No video stream found"); } if (demux.hasAudio) { var audioStreamInfo = moviePlayerBase.movie.demux.audioStreamInfo; var audioDecoder = moviePlayerBase.movie.audioDecoder; DrawLabelValue("Audio fourCC", RiffParser.FromFourCC(audioStreamInfo.codecFourCC)); DrawLabelValue("Audio decoder", audioDecoder != null ? audioDecoder.GetType().ToString() : "N/A"); DrawLabelValue("audioFormat", audioStreamInfo.audioFormat.ToString("X")); DrawLabelValue("channels", audioStreamInfo.channels.ToString()); DrawLabelValue("sampleCount", audioStreamInfo.sampleCount.ToString()); DrawLabelValue("sampleSize", audioStreamInfo.sampleSize.ToString()); DrawLabelValue("sampleRate", audioStreamInfo.sampleRate.ToString()); DrawLabelValue("lengthBytes", audioStreamInfo.lengthBytes.ToString()); DrawLabelValue("lengthSeconds", audioStreamInfo.lengthSeconds.ToString()); } else { GUILayout.Label("No audio stream found"); } } } else { GUILayout.Label("No movie loaded"); } GUI.DragWindow(new Rect(0, 0, 4000, 4000)); }
private static void ParseChunkIndex(AtomicBinaryReader reader, long p, ref AviStreamIndex index) { // read ix.. chunk id and size. do sanity check uint ixChunkFCC = reader.ReadUInt32(ref p); uint ixChunkFCCb = (ixChunkFCC & 0x0000FFFF) | 0x20200000; if (ixChunkFCCb != RiffParser.ToFourCC("ix ") && ixChunkFCC != RiffParser.ToFourCC("indx")) { throw new MpException("Unexpected chunk id for index " + RiffParser.FromFourCC(ixChunkFCC) + " for stream " + RiffParser.FromFourCC(index.streamId)); } uint ixChunkSize = reader.ReadUInt32(ref p); // read index data header and do sanity check ushort wLongsPerEntry = reader.ReadUInt16(ref p); byte bSubIndexType = reader.ReadByte(ref p); byte bIndexType = reader.ReadByte(ref p); uint nEntriesInUse = reader.ReadUInt32(ref p); uint streamId = reader.ReadUInt32(ref p); #if MP_DEBUG //Debug.Log("Parsing index for " + RiffParser.FromFourCC(index.streamId)); #endif if (bIndexType != (int)AviStreamIndex.Type.CHUNKS || bSubIndexType != 0 || streamId != index.streamId || wLongsPerEntry != 2 || ixChunkSize < 4 * wLongsPerEntry * nEntriesInUse + 24) { throw new MpException("Broken or unsupported index for stream " + RiffParser.FromFourCC(streamId) + ". " + streamId + "!=" + index.streamId + ", wLongsPerEntry=" + wLongsPerEntry + ", bIndexType=" + bIndexType + ", bSubIndexType=" + bSubIndexType); } long qwBaseOffset = reader.ReadInt64(ref p); p += 4; // not caring about reserved bytes // reading it all at once is about 10x faster than reading individual uints. // the index chunk is not that big, so it's ok for GC too. var uintBuf = new uint[nEntriesInUse * 2]; reader.Read(ref p, uintBuf, 0, (int)nEntriesInUse * 2); for (int i = 0; i < nEntriesInUse; i++) { var entry = new AviStreamIndex.Entry(); entry.chunkOffset = qwBaseOffset + uintBuf [2 * i]; uint len = uintBuf [2 * i + 1]; entry.chunkLength = (int)(len & 0x7FFFFFFF); if ((len & 0x80000000) == 0) { entry.isKeyframe = true; } index.entries.Add(entry); } }
private unsafe void DecodeAVIStream(RiffParser rp, int unpaddedLength, int length) { byte[] ba = new byte[length]; if (rp.ReadData(ba, 0, length) != length) { throw new RiffParserException("Problem reading AVI header."); } fixed(Byte *bp = &ba[0]) { AVISTREAMHEADER *avi = (AVISTREAMHEADER *)bp; if (AviRiffData.streamtypeVIDEO == avi->fccType) { m_vidHandler = RiffParser.FromFourCC(avi->fccHandler); if (avi->dwScale > 0) { m_vidDataRate = (double)avi->dwRate / (double)avi->dwScale; } else { m_vidDataRate = 0.0; } } else if (AviRiffData.streamtypeAUDIO == avi->fccType) { if (AviRiffData.ckidMP3 == avi->fccHandler) { m_audHandler = "MP3"; } else { m_audHandler = RiffParser.FromFourCC(avi->fccHandler); } if (avi->dwScale > 0) { m_audDataRate = 8.0 * (double)avi->dwRate / (double)avi->dwScale; if (avi->dwSampleSize > 0) { m_audDataRate /= (double)avi->dwSampleSize; } } else { m_audDataRate = 0.0; } } } }
public async void CheckFile() { StorageFolder storageFolder = KnownFolders.MusicLibrary; var checkFile = await storageFolder.TryGetItemAsync(this.Recorder.FileName); if (checkFile == null) { this.Info.Text = "Wav not recorded ..."; } else { StorageFile storageFile = await storageFolder.GetFileAsync(this.Recorder.FileName); var parser = new RiffParser(); // read file await Windows.System.Threading.ThreadPool.RunAsync( async (workItem) => { IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read); Stream sstream = stream.AsStream(); parser.OpenFile(sstream); // Define the processing delegates RiffParser.ProcessChunkElement pc = ProcessChunk; // Read all top level elements and chunks int size = parser.DataSize; while (size > 0) { // Prefix the line with the current top level type var info = (RiffParser.FromFourCC(parser.FileType) + " (" + size.ToString() + "): "); // Get the next element (if there is one) if (false == parser.ReadElement(ref size, pc, null)) { break; } } // Close the stream parser.CloseFile(); }); } }
private void CheckFile(string filename) { rp.OpenFile(filename); txtFileFormat.Text = RiffParser.FromFourCC(rp.FileRIFF); txtFileType.Text = RiffParser.FromFourCC(rp.FileType); if (txtFileType.Text.StartsWith("CDR")) { } // Is this a type we are familiar with? if (RiffParser.ckidAVI == rp.FileType) { dh.ProcessMainAVI(); lbl1a.Text = dh.FrameSize; lbl2a.Text = dh.FrameRate; lbl3a.Text = dh.TotalFrames; lbl4a.Text = dh.TotalTime; lbl5a.Text = dh.NumStreams; lbl1b.Text = dh.ISFT; lbl2b.Text = dh.VideoHandler; lbl3b.Text = dh.VideoDataRate; lbl4b.Text = dh.AudioHandler; lbl5b.Text = dh.AudioDataRate; pnlAVI.Visible = true; } else if (RiffParser.ckidWAV == rp.FileType) { dh.ProcessMainWAVE(); lbl1a.Text = dh.NumChannels; lbl2a.Text = dh.BitsPerSample; lbl3a.Text = dh.BitsPerSec; lbl4a.Text = dh.SamplesPerSec; pnlAVI.Visible = true; } else if (RiffParser.ckidRMID == rp.FileType) { } rp.CloseFile(); }
private void ProcessCDRList(RiffParser rp, int FourCC, int length) { Console.WriteLine(String.Format("LIST:{0:s}", RiffParser.FromFourCC(FourCC))); rp.SkipData(length); }
private void ProcessCDRChunk(RiffParser rp, int FourCC, int unpaddedLength, int length) { Console.WriteLine(String.Format("Chunk:{0:s}", RiffParser.FromFourCC(FourCC))); rp.SkipData(length); }
private void ProcessAviChunk(RiffParser rp, uint fourCC, int unpaddedLength, int paddedLength) { //Debug.Log("CHUNK " + RiffParser.FromFourCC(fourCC) + " " + rp.Position + " " + unpaddedLength + " " + paddedLength); switch (fourCC) { case ID_avih: avi.avih = ParseMainHeader(rp.reader, rp.Position); break; case ID_strh: AVIStreamHeader strh = ParseStreamHeader(rp.reader, rp.Position); currentStrh4CC = strh.fccType; if (currentStrh4CC == FCC_vids) { avi.strhVideo = strh; } else if (currentStrh4CC == FCC_auds) { avi.strhAudio = strh; } else { #if MP_DEBUG Debug.LogWarning("Skipping unknown stream header with fccType=" + currentStrh4CC); #endif } break; case ID_strf: if (currentStrh4CC == FCC_vids) { avi.strfVideo = ParseVideoFormatHeader(rp.reader, rp.Position); } else if (currentStrh4CC == FCC_auds) { avi.strfAudio = ParseAudioFormatHeader(rp.reader, rp.Position); } break; case ID_idx1: idx1Offset = rp.Position; idx1Size = unpaddedLength; // index.idx1 will be filled later in ParseIndex method break; case ID_dmlh: // OpenDML header avi.odml = ParseOdmlHeader(rp.reader, rp.Position); break; case ID_indx: // OpenDML index uint streamId; var index = ParseOdmlIndex(rp.reader, rp.Position, out streamId); if (streamId == ID_00dc || streamId == ID_00db) { avi.videoIndex = index; } else if (streamId == ID_01wb) { avi.audioIndex = index; } #if MP_DEBUG else { Debug.LogWarning("Ignoring index for unknown stream " + RiffParser.FromFourCC(streamId)); } #endif break; #if MP_DEBUG default: // comment in for logging chunks that are ignored (not relevant for us) //Debug.Log("Ignoring CHUNK " + RiffParser.FromFourCC(fourCC) + " " + unpaddedLength + " " + paddedLength); break; #endif } }
private static AviStreamIndex ParseOdmlIndex(AtomicBinaryReader reader, long p, out uint streamId) { ushort wLongsPerEntry = reader.ReadUInt16(ref p); byte bSubIndexType = reader.ReadByte(ref p); byte bIndexType = reader.ReadByte(ref p); uint nEntriesInUse = reader.ReadUInt32(ref p); streamId = reader.ReadUInt32(ref p); var index = new AviStreamIndex(); index.streamId = streamId; // if there is AVI_INDEX_OF_CHUNKS (superindex) in this element if (bIndexType == (byte)AviStreamIndex.Type.SUPERINDEX) { p += 3 * 4; // not caring about reserved bytes #if MP_DEBUG //Debug.Log("Parsing superindex for " + RiffParser.FromFourCC(streamId)); #endif // sanity check if (bSubIndexType != 0 || wLongsPerEntry != 4) { #if MP_DEBUG Debug.LogWarning("Broken superindex for stream " + RiffParser.FromFourCC(streamId) + ", but trying to continue. " + bSubIndexType + " " + wLongsPerEntry); #endif } for (uint i = 0; i < nEntriesInUse; i++) { long qwOffset = reader.ReadInt64(ref p); int dwSize = reader.ReadInt32(ref p); reader.ReadInt32(ref p); // dwDuration. don't care if (qwOffset != 0) { long currentStreamPos = p; p = qwOffset; // reduce memory allocations by (over)estimating entry count from index size in bytes index.entries.Capacity += dwSize / 8; ParseChunkIndex(reader, p, ref index); p = currentStreamPos; } } } // if there is AVI_INDEX_OF_CHUNKS (chunk index) in here else if (bIndexType == (byte)AviStreamIndex.Type.CHUNKS) { // seek back to the beginning of this chunk (12bytes read here, 8bytes read by RiffParser) ParseChunkIndex(reader, p - 20, ref index); } else { throw new MpException("Unsupported index type " + bIndexType + " encountered for stream " + RiffParser.FromFourCC(streamId)); } index.entries.TrimExcess(); return(index); }