Example #1
0
        /// <summary>
        /// Given a byte[] containing a video frame, return the video MediaType.
        /// </summary>
        /// <param name="frame"></param>
        /// <param name="compressionData"></param>
        /// <returns></returns>
        private static MediaTypeVideoInfo VideoMediaTypeFromFrame(byte[] frame, out byte[] compressionData)
        {
            if (frame == null)
            {
                compressionData = null;
                return(null);
            }

            BufferChunk bc         = new BufferChunk(frame);
            short       headerSize = bc.NextInt16();        //first short tells us the header size
            BufferChunk header     = bc.NextBufferChunk(headerSize);

            //The header contains a custom serialization of AM_SAMPLE2_PROPERTIES followed by
            // AM_MEDIA_TYPE and an optional format type.

            //AM_SAMPLE2_PROPERTIES
            BufferChunk AmSample2Properties = header.NextBufferChunk(48);

            //AM_MEDIA_TYPE
            MediaTypeVideoInfo vmt = new MediaTypeVideoInfo();

            ReconstituteBaseMediaType((MediaType)vmt, header);
            compressionData = null;
            if (vmt.FormatType == FormatType.VideoInfo)
            {
                ReconstituteVideoFormat(vmt, header, out compressionData);
            }
            return(vmt);
        }
Example #2
0
        /// <summary>
        /// Take the DirectShow header off the frame and return the remainder.
        /// Also indicate whether the keyframe flag is set.
        /// </summary>
        /// <param name="frame"></param>
        /// <returns></returns>
        public static BufferChunk FrameToSample(BufferChunk frame, out bool keyframe)
        {
            short       headerSize = frame.NextInt16();        //first short tells us the header size
            BufferChunk header     = null;

            header = frame.NextBufferChunk(headerSize);

            AM_SAMPLE2_PROPERTIES amsp = ReconstituteSampleProperties(header);

            if ((amsp.dwSampleFlags & 1) > 0)
            {
                keyframe = true;
            }
            else
            {
                keyframe = false;
            }
            //Debug.WriteLine("FrameToSample returning sample of size=" + frame.Length);
            return(frame);
        }
Example #3
0
        override public void Run()
        {
            BufferChunk bc = new BufferChunk(7);
            short s = 25000;
            int i = 545434;
            byte b = 56;

            bc += s;
            bc += i;
            bc += b;

            if (bc.NextInt16() != s)
                throw new TestCaseException("Short failed for " + s);
            if (bc.NextInt32() != i)
                throw new TestCaseException("Int failed for " + i);
            if (bc.NextByte() != b)
                throw new TestCaseException("Byte failed for " + b);

            bc.Reset();

            s = short.MaxValue;
            i = int.MaxValue;
            b = byte.MaxValue;

            bc += s;
            bc += i;
            bc += b;

            if (bc.NextInt16() != s)
                throw new TestCaseException("Short failed for " + s);
            if (bc.NextInt32() != i)
                throw new TestCaseException("Int failed for " + i);
            if (bc.NextByte() != b)
                throw new TestCaseException("Byte failed for " + b);

            bc.Reset();

            s = short.MinValue;
            i = int.MinValue;
            b = byte.MinValue;

            bc += s;
            bc += i;
            bc += b;

            if (bc.NextInt16() != s)
                throw new TestCaseException("Short failed for " + s);
            if (bc.NextInt32() != i)
                throw new TestCaseException("Int failed for " + i);
            if (bc.NextByte() != b)
                throw new TestCaseException("Byte failed for " + b);

        }
Example #4
0
            /// <summary>
            /// Read the next sample at the given timestamp (or within the FUDGE_FACTOR range.)
            /// Return zero if there is no sample available for this timestamp.
            /// </summary>
            /// <param name="bitsPerSample"></param>
            /// <returns></returns>
            public long ReadSample(int bytesPerSample, long timestamp)
            {
                if ((buffer == null) || (buffer.Length < bytesPerSample))
                {
                    if ((buffer != null) && (buffer.Length > 0))
                    {
                        //Debug.WriteLine(".");
                        Debug.WriteLine("Warning: An audio chunk appeared to contain a fractional part of a sample which will be discarded.");
                    }
                    FillBuffer();
                }

                if (exhausted)
                {
                    return(0);
                }

                bool convertToStereo = false;
                bool convertToMono   = false;

                if (currentChannels != targetChannels)
                {
                    if (targetChannels == 2)
                    {
                        convertToStereo = true;
                    }
                    else
                    {
                        convertToMono = true;
                    }
                }

                long sampleAsLong = 0;

                if (Math.Abs(nextTimestamp - timestamp) < FUDGE_FACTOR)
                {
                    nextTimestamp += this.ticksPerSample;
                    if ((convertToStereo) && (sampleCounter % 2 == 1))
                    {
                        sampleAsLong = previousSample;
                    }
                    else
                    {
                        switch (bytesPerSample)
                        {
                        case 1:
                            sampleAsLong = buffer.NextByte();
                            if (convertToMono)
                            {
                                sampleAsLong += buffer.NextByte();
                                sampleAsLong  = sampleAsLong / 2;
                            }
                            break;

                        case 2:
                            sampleAsLong = BitConverter.ToInt16(buffer.Buffer, buffer.Index);
                            //Note that NextInt16, NextInt32 assume the wrong byte order.  We just use them to
                            //update the BufferChunk.Index and Length.
                            buffer.NextInt16();
                            if (convertToMono)
                            {
                                sampleAsLong += BitConverter.ToInt16(buffer.Buffer, buffer.Index);
                                buffer.NextInt16();
                                sampleAsLong = sampleAsLong / 2;
                            }
                            break;

                        case 4:
                            sampleAsLong = BitConverter.ToInt32(buffer.Buffer, buffer.Index);
                            buffer.NextInt32();
                            if (convertToMono)
                            {
                                sampleAsLong += BitConverter.ToInt32(buffer.Buffer, buffer.Index);
                                buffer.NextInt32();
                                sampleAsLong = sampleAsLong / 2;
                            }
                            break;

                        default:
                            break;
                        }
                    }
                }

                this.previousSample = sampleAsLong;
                this.sampleCounter++;
                return(sampleAsLong);
            }
Example #5
0
        override public void Run()
        {
            BufferChunk bc = new BufferChunk(7);
            short       s  = 25000;
            int         i  = 545434;
            byte        b  = 56;

            bc += s;
            bc += i;
            bc += b;

            if (bc.NextInt16() != s)
            {
                throw new TestCaseException("Short failed for " + s);
            }
            if (bc.NextInt32() != i)
            {
                throw new TestCaseException("Int failed for " + i);
            }
            if (bc.NextByte() != b)
            {
                throw new TestCaseException("Byte failed for " + b);
            }

            bc.Reset();

            s = short.MaxValue;
            i = int.MaxValue;
            b = byte.MaxValue;

            bc += s;
            bc += i;
            bc += b;

            if (bc.NextInt16() != s)
            {
                throw new TestCaseException("Short failed for " + s);
            }
            if (bc.NextInt32() != i)
            {
                throw new TestCaseException("Int failed for " + i);
            }
            if (bc.NextByte() != b)
            {
                throw new TestCaseException("Byte failed for " + b);
            }

            bc.Reset();

            s = short.MinValue;
            i = int.MinValue;
            b = byte.MinValue;

            bc += s;
            bc += i;
            bc += b;

            if (bc.NextInt16() != s)
            {
                throw new TestCaseException("Short failed for " + s);
            }
            if (bc.NextInt32() != i)
            {
                throw new TestCaseException("Int failed for " + i);
            }
            if (bc.NextByte() != b)
            {
                throw new TestCaseException("Byte failed for " + b);
            }
        }