Example #1
0
        static void DumpStreamFormat(IntPtr icPtr, FFmpeg.AVFormatContext ic, object format, int i, int index, bool isOutput)
        {
            var flags = isOutput ? ((FFmpeg.AVOutputFormat)format).flags : ((FFmpeg.AVInputFormat)format).flags;
            var st    = (FFmpeg.AVStream)Marshal.PtrToStructure(ic.streams[i], typeof(FFmpeg.AVStream));
            int g     = (int)FFmpeg.ff_gcd(st.time_base.num, st.time_base.den);

            var buf = new StringBuilder(256);

            FFmpeg.avcodec_string(buf, buf.Capacity, st.codec, isOutput ? 1 : 0);
            Console.Write("    Stream #{0}.{1}", index, i);
            if ((flags & FFmpeg.AVFMT_SHOW_IDS) != 0)
            {
                Console.Write("[0x{0:x}]", st.id);
            }
            if (st.language.Length > 0)
            {
                Console.Write("({0})", st.language);
            }
            Console.Write(", {0}/{1}", st.time_base.num / g, st.time_base.den / g);
            Console.Write(": {0}", buf);
            var codec = (FFmpeg.AVCodecContext)Marshal.PtrToStructure(st.codec, typeof(FFmpeg.AVCodecContext));

            if (codec.codec_type == FFmpeg.CodecType.CODEC_TYPE_VIDEO)
            {
                if (st.r_frame_rate.den != 0 && st.r_frame_rate.num != 0)
                {
                    Console.Write(", {0:f} tb(r)", FFmpeg.av_q2d(st.r_frame_rate));
                }
                else
                {
                    Console.Write(", {0:f} tb(c)", 1 / FFmpeg.av_q2d(codec.time_base));
                }
            }
            Console.WriteLine();
        }
Example #2
0
        private PendingFrame ReadVideoFrame()
        {
            int ret;

            while (true)
            {
                ret = FFmpeg.av_read_frame(_pFormatContext, _pPacket);
                if (ret < 0)
                {
                    var packet = new FFmpeg.AVPacket();
                    packet.dts      = _lastPacket.dts + PTSPerField * _videoCodecContext.ticks_per_frame;
                    packet.pts      = _lastPacket.pts + PTSPerField * _videoCodecContext.ticks_per_frame;
                    packet.duration = _lastPacket.duration;
                    int sizeOfPacket = Marshal.SizeOf(packet);
                    var pPacket      = Marshal.AllocHGlobal(sizeOfPacket);
                    RtlZeroMemory(pPacket, sizeOfPacket);
                    Marshal.StructureToPtr(packet, pPacket, true);
                    int frameFinished = 0;
                    ret = FFmpeg.avcodec_decode_video2(_pVideoCodecContext, _pFrameOrig, ref frameFinished, pPacket);
                    if (frameFinished != 0)
                    {
                        return(ProcessFrame());
                    }
                    break;
                }

                _formatContext = (FFmpeg.AVFormatContext)Marshal.PtrToStructure(_pFormatContext, typeof(FFmpeg.AVFormatContext));

                _lastPacket = (FFmpeg.AVPacket)Marshal.PtrToStructure(_pPacket, typeof(FFmpeg.AVPacket));

                if (_lastPacket.stream_index == _videoStreamIndex)
                {
                    // Decode the video frame
                    int frameFinished = 0;
                    ret = FFmpeg.avcodec_decode_video2(_pVideoCodecContext, _pFrameOrig, ref frameFinished, _pPacket);

                    FFmpeg.av_free_packet(_pPacket);

                    if (frameFinished != 0)
                    {
                        return(ProcessFrame());
                    }
                }
            }

            return(null);
        }
Example #3
0
        public bool Open(byte[] bytes)
        {
            if ((bytes == null) || (bytes.Length == 0))
            {
                return(false);
            }
            streamHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            IntPtr ptr = streamHandle.AddrOfPinnedObject();

            if (videoOpened)
            {
                return(false);
            }
            videoOpened = true;
            string filename = string.Concat(new object[] { "memory:", ptr, "|", bytes.Length });

            if (FFmpeg.av_open_input_file(out pFormatCtx, filename, IntPtr.Zero, bytes.Length, IntPtr.Zero) != 0)
            {
                throw new Exception("Couldn't open input file");
            }
            if (FFmpeg.av_find_stream_info(pFormatCtx) < 0)
            {
                throw new Exception("Couldn't find stream info");
            }
            FFmpeg.dump_format(pFormatCtx, 0, filename, 0);
            formatContext = (FFmpeg.AVFormatContext)Marshal.PtrToStructure(pFormatCtx, typeof(FFmpeg.AVFormatContext));
            videoStream   = -1;
            int num2 = formatContext.nb_streams;

            for (int i = 0; i < num2; i++)
            {
                var _stream =
                    (FFmpeg.AVStream)Marshal.PtrToStructure(formatContext.streams[i], typeof(FFmpeg.AVStream));
                var context =
                    (FFmpeg.AVCodecContext)Marshal.PtrToStructure(_stream.codec, typeof(FFmpeg.AVCodecContext));
                if (context.codec_type == FFmpeg.CodecType.CODEC_TYPE_VIDEO)
                {
                    videoStream = i;
                    this.stream = _stream;
                    codecCtx    = context;
                    pCodecCtx   = this.stream.codec;
                    break;
                }
            }
            if (videoStream == -1)
            {
                throw new Exception("couldn't find video stream");
            }
            FrameDelay = FFmpeg.av_q2d(stream.time_base);
            pCodec     = FFmpeg.avcodec_find_decoder(codecCtx.codec_id);
            if (pCodec == IntPtr.Zero)
            {
                throw new Exception("couldn't find decoder");
            }
            if (FFmpeg.avcodec_open(pCodecCtx, pCodec) < 0)
            {
                throw new Exception("couldn't open codec");
            }
            pFrame    = FFmpeg.avcodec_alloc_frame();
            pFrameRGB = FFmpeg.avcodec_alloc_frame();
            if (pFrameRGB == IntPtr.Zero)
            {
                throw new Exception("couldn't allocate RGB frame");
            }
            int cb = FFmpeg.avpicture_get_size(6, codecCtx.width, codecCtx.height);

            buffer = Marshal.AllocHGlobal(cb);
            FFmpeg.avpicture_fill(pFrameRGB, buffer, 6, codecCtx.width, codecCtx.height);
            packet = Marshal.AllocHGlobal(0x39);
            for (int j = 0; j < BufferSize; j++)
            {
                FrameBuffer[j] = new byte[(width * height) * 4];
            }
            decodingThread = new Thread(Decode);
            decodingThread.IsBackground = true;
            decodingThread.Start();
            return(true);
        }
Example #4
0
        public bool Open(string path)
        {
            Reset();

            int ret;

            ret = FFmpeg.av_open_input_file(out pFormatContext, path, IntPtr.Zero, 0, IntPtr.Zero);

            if (ret < 0)
            {
                Console.WriteLine("couldn't opne input file");
                return(false);
            }

            ret = FFmpeg.av_find_stream_info(pFormatContext);

            if (ret < 0)
            {
                Console.WriteLine("couldnt find stream informaion");
                return(false);
            }

            formatContext = (FFmpeg.AVFormatContext)
                            Marshal.PtrToStructure(pFormatContext, typeof(FFmpeg.AVFormatContext));

            for (int i = 0; i < formatContext.nb_streams; ++i)
            {
                FFmpeg.AVStream stream = (FFmpeg.AVStream)
                                         Marshal.PtrToStructure(formatContext.streams[i], typeof(FFmpeg.AVStream));

                FFmpeg.AVCodecContext codec = (FFmpeg.AVCodecContext)
                                              Marshal.PtrToStructure(stream.codec, typeof(FFmpeg.AVCodecContext));

                if (codec.codec_type == FFmpeg.CodecType.CODEC_TYPE_AUDIO &&
                    audioStartIndex == -1)
                {
                    //this.pAudioCodecContext = stream.codec;
                    //this.pAudioStream = formatContext.streams[i];
                    this.audioCodecContext = codec;
                    this.audioStartIndex   = i;
                    this.timebase          = stream.time_base;

                    pAudioCodec = FFmpeg.avcodec_find_decoder(this.audioCodecContext.codec_id);
                    if (pAudioCodec == IntPtr.Zero)
                    {
                        Console.WriteLine("couldn't find codec");
                        return(false);
                    }

                    FFmpeg.avcodec_open(stream.codec, pAudioCodec);
                }
            }

            if (audioStartIndex == -1)
            {
                Console.WriteLine("Couldn't find audio streamn");
                return(false);
            }

            audioSampleRate = audioCodecContext.sample_rate;

            if (audioCodecContext.channels == 1)
            {
                //format = Al.AL_FORMAT_MONO16;
            }
            else
            {
                //format = Al.AL_FORMAT_STEREO16;
            }

            return(true);
        }
Example #5
0
        public void Open(string filename)
        {
            int ret;

            Reset();

            _filename = filename;

            var dictionary = new FFmpeg.AVDictionary();

            dictionary.count = 0;
            ret = FFmpeg.avformat_open_input(out _pFormatContext, filename, IntPtr.Zero, dictionary);
            if (ret < 0)
            {
                throw new Exception("Failed to open input file: " + ret.ToString());
            }

            ret = FFmpeg.av_find_stream_info(_pFormatContext);
            if (ret < 0)
            {
                throw new Exception("Failed to find stream information: " + ret.ToString());
            }

            _formatContext = (FFmpeg.AVFormatContext)Marshal.PtrToStructure(_pFormatContext, typeof(FFmpeg.AVFormatContext));

            for (int streamIndex = 0; streamIndex < _formatContext.nb_streams; ++streamIndex)
            {
                //IntPtr pStream = _formatContext.streams[streamIndex];
                IntPtr pStream      = Marshal.ReadIntPtr(_formatContext.streams, streamIndex * 4);
                var    stream       = (FFmpeg.AVStream)Marshal.PtrToStructure(pStream, typeof(FFmpeg.AVStream));
                var    codecContext = (FFmpeg.AVCodecContext)Marshal.PtrToStructure(stream.codec, typeof(FFmpeg.AVCodecContext));

                if (codecContext.codec_type == FFmpeg.CodecType.CODEC_TYPE_VIDEO)
                {
                    _videoStreamIndex   = streamIndex;
                    _pVideoStream       = pStream;
                    _videoStream        = stream;
                    _pVideoCodecContext = stream.codec;
                    _videoCodecContext  = codecContext;

                    if (Resolution != ResolutionOption.Full)
                    {
                        Marshal.WriteInt32(_pVideoCodecContext, Marshal.OffsetOf(typeof(FFmpeg.AVCodecContext), "lowres").ToInt32(), (int)Resolution);
                    }

                    _pVideoCodecDecoder = FFmpeg.avcodec_find_decoder(_videoCodecContext.codec_id);
                    if (_pVideoCodecDecoder == IntPtr.Zero)
                    {
                        throw new Exception("Failed to find decoder");
                    }

                    ret = FFmpeg.avcodec_open(stream.codec, _pVideoCodecDecoder);
                    if (ret < 0)
                    {
                        throw new Exception("Failed to open codec: " + ret.ToString());
                    }

                    _videoCodecContext = (FFmpeg.AVCodecContext)Marshal.PtrToStructure(stream.codec, typeof(FFmpeg.AVCodecContext));

                    //Allocate buffers for original frame
                    _pFrameOrig = FFmpeg.avcodec_alloc_frame();

                    //Allocate buffers for RGB frame
                    _scalerY = new SwsScaler(_videoCodecContext);
                    _scalerY.DstPixelFormat = SwsScaler.PixelFormat.Y;

                    //Allocate buffers for RGB frame
                    _scalerRGB = new SwsScaler(_videoCodecContext);

                    // Allocate packet memory
                    int sizeOfPacket = Marshal.SizeOf(typeof(FFmpeg.AVPacket));
                    _pPacket = Marshal.AllocHGlobal(sizeOfPacket);
                    RtlZeroMemory(_pPacket, sizeOfPacket);
                }
                //else if (codecContext.codec_type == FFmpeg.CodecType.CODEC_TYPE_AUDIO)
                //{
                //    _audioStreamIndex = i;
                //    _pAudioStream = _formatContext.streams[i];
                //    _audioStream = stream;
                //    _pAudioCodec = stream.codec;
                //    _audioCodecContext = codecContext;
                //}
            }

            // Seek to the start of the file to reset dts values.
            ret = FFmpeg.avformat_seek_file(_pFormatContext, _videoStreamIndex, 0, 0, Int64.MaxValue, FFmpeg.AVSEEK_FLAG.AVSEEK_FLAG_NONE);
            if (ret < 0)
            {
                throw new Exception("Failed to seek to first frame: " + ret.ToString());
            }
            FFmpeg.avcodec_flush_buffers(_pVideoCodecContext);

            // Read the first frame to set initial dts values
            ReadVideoFrame();

            if (_lastFieldNumber == -1)
            {
                if (_filename == @"F:\Convert\ComskipTest\Chuck - 4x02 - Retune\(2012-09-10 03-55) Chuck - 4x02 - Chuck Versus the Suitcase.m2v")
                {
                    _lastFieldNumber = 160295;
                }
                else
                {
                    SeekToPTS(Int64.MaxValue, false);
                    _lastFieldNumber = _pendingFrame.Fields.Last().FieldNumber;
                }
            }

            SeekToPTS(0, false);
            return;
        }
Example #6
0
        public FFmpegDecoder(Stream stream)
        {
            if (!Enabled)
            {
                try {
                    FFmpeg.av_register_all();
                    Enabled = true;
                } catch (Exception ex) {
                    throw ex;
                }
            }

            stream.Position = 0;
            Stream          = new TemporaryStream();
            Util.StreamCopy(Stream, stream, stream.Length);
            Stream.ClosePersist();

            FFmpeg.av_open_input_file(out FormatPointer, Stream.Name, IntPtr.Zero, 0, IntPtr.Zero);
            if (FFmpeg.av_find_stream_info(FormatPointer) < 0)
            {
                throw new FormatException();
            }
            Format = (FFmpeg.AVFormatContext)Marshal.PtrToStructure(FormatPointer, typeof(FFmpeg.AVFormatContext));
            for (StreamIndex = 0; StreamIndex < Format.nb_streams; StreamIndex++)
            {
                if (Format.streams[StreamIndex] == IntPtr.Zero)
                {
                    continue;
                }
                AVStream = (FFmpeg.AVStream)Marshal.PtrToStructure(Format.streams[StreamIndex], typeof(FFmpeg.AVStream));
                Codec    = (FFmpeg.AVCodecContext)Marshal.PtrToStructure(AVStream.codec, typeof(FFmpeg.AVCodecContext));
                if (Codec.codec_type == FFmpeg.CodecType.CODEC_TYPE_AUDIO)
                {
                    DecoderPointer = FFmpeg.avcodec_find_decoder(Codec.codec_id);
                    break;
                }
            }

            if (DecoderPointer == IntPtr.Zero)
            {
                throw new FormatException();
            }

            FFmpeg.avcodec_open(AVStream.codec, DecoderPointer);

            Channels   = Codec.channels;
            SampleRate = Codec.sample_rate;
            if (AVStream.duration < 0)
            {
                Samples = long.MaxValue;
            }
            else
            {
                Samples = AVStream.time_base.num * AVStream.duration * SampleRate / AVStream.time_base.den;
            }

            PacketPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FFmpeg.AVPacket)));
            //FFmpegBufferSize = (FFmpeg.AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
            FFmpegBufferSize = BufferSize * Channels * 2;
            FFmpegBuffer     = Marshal.AllocHGlobal(FFmpegBufferSize);
            AudioBuffer      = new JaggedShortArray(Channels, BufferSize);

            CacheBuffer = new byte[FFmpegBufferSize];
            Cache       = new MemoryStream();
            CacheOffset = 0;
            CacheLength = 0;
        }
Example #7
0
        public bool Open(byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0)
            {
                return(false);
            }
            this.streamHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            IntPtr intPtr = this.streamHandle.AddrOfPinnedObject();

            if (this.videoOpened)
            {
                return(false);
            }
            this.videoOpened = true;
            string text = fullfilename;

            _fname = fullfilename;
            int num = FFmpeg.av_open_input_file(out this.pFormatCtx, text, IntPtr.Zero, bytes.Length, IntPtr.Zero);

            if (num != 0)
            {
                throw new Exception("Couldn't open input file");
            }
            num = FFmpeg.av_find_stream_info(this.pFormatCtx);
            if (num < 0)
            {
                throw new Exception("Couldn't find stream info");
            }
            FFmpeg.dump_format(this.pFormatCtx, 0, text, 0);
            this.formatContext = (FFmpeg.AVFormatContext)Marshal.PtrToStructure(this.pFormatCtx, typeof(FFmpeg.AVFormatContext));
            this.videoStream   = -1;
            int nb_streams = this.formatContext.nb_streams;

            for (int i = 0; i < nb_streams; i++)
            {
                FFmpeg.AVStream       aVStream       = (FFmpeg.AVStream)Marshal.PtrToStructure(this.formatContext.streams[i], typeof(FFmpeg.AVStream));
                FFmpeg.AVCodecContext aVCodecContext = (FFmpeg.AVCodecContext)Marshal.PtrToStructure(aVStream.codec, typeof(FFmpeg.AVCodecContext));
                if (aVCodecContext.codec_type == FFmpeg.CodecType.CODEC_TYPE_VIDEO)
                {
                    this.videoStream = i;
                    this.stream      = aVStream;
                    this.codecCtx    = aVCodecContext;
                    this.pCodecCtx   = this.stream.codec;
                    break;
                }
            }
            if (this.videoStream == -1)
            {
                throw new Exception("couldn't find video stream");
            }
            this.FrameDelay = av_q2d(this.stream.time_base);
            this.pCodec     = FFmpeg.avcodec_find_decoder(this.codecCtx.codec_id);
            if (this.pCodec == IntPtr.Zero)
            {
                throw new Exception("couldn't find decoder");
            }
            if (FFmpeg.avcodec_open(this.pCodecCtx, this.pCodec) < 0)
            {
                throw new Exception("couldn't open codec");
            }
            this.pFrame    = FFmpeg.avcodec_alloc_frame();
            this.pFrameRGB = FFmpeg.avcodec_alloc_frame();
            if (this.pFrameRGB == IntPtr.Zero)
            {
                throw new Exception("couldn't allocate RGB frame");
            }
            int cb = FFmpeg.avpicture_get_size(6, this.codecCtx.width, this.codecCtx.height);

            this.buffer = Marshal.AllocHGlobal(cb);
            FFmpeg.avpicture_fill(this.pFrameRGB, this.buffer, 6, this.codecCtx.width, this.codecCtx.height);
            this.packet = Marshal.AllocHGlobal(57);
            for (int j = 0; j < this.BufferSize; j++)
            {
                this.FrameBuffer[j] = new byte[this.width * this.height * 4];
            }
            this.decodingThread = new Thread(new ThreadStart(this.Decode));
            this.decodingThread.IsBackground = true;
            this.decodingThread.Start();
            return(true);
        }
Example #8
0
        public bool Open(byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0)
            {
                return(false);
            }

            streamHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            IntPtr ptr = streamHandle.AddrOfPinnedObject();

            if (videoOpened)
            {
                return(false);
            }

            videoOpened = true;

            string path = "memory:" + ptr + "|" + bytes.Length;

            int ret = FFmpeg.av_open_input_file(out pFormatCtx, path, IntPtr.Zero, bytes.Length, IntPtr.Zero);

            if (ret != 0)
            {
                throw new Exception("Couldn't open input file");
            }

            ret = FFmpeg.av_find_stream_info(pFormatCtx);

            if (ret < 0)
            {
                throw new Exception("Couldn't find stream info");
            }

            FFmpeg.dump_format(pFormatCtx, 0, path, 0);

            formatContext =
                (FFmpeg.AVFormatContext)Marshal.PtrToStructure(pFormatCtx, typeof(FFmpeg.AVFormatContext));

            videoStream = -1;
            int nbStreams = formatContext.nb_streams;

            for (int i = 0; i < nbStreams; i++)
            {
                FFmpeg.AVStream str = (FFmpeg.AVStream)
                                      Marshal.PtrToStructure(formatContext.streams[i], typeof(FFmpeg.AVStream));
                FFmpeg.AVCodecContext codec = (FFmpeg.AVCodecContext)
                                              Marshal.PtrToStructure(str.codec, typeof(FFmpeg.AVCodecContext));

                if (codec.codec_type == FFmpeg.CodecType.CODEC_TYPE_VIDEO)
                {
                    videoStream = i;
                    stream      = str;
                    codecCtx    = codec;
                    pCodecCtx   = stream.codec;
                    break;
                }
            }
            if (videoStream == -1)
            {
                throw new Exception("couldn't find video stream");
            }

            FrameDelay = FFmpeg.av_q2d(stream.time_base);

            pCodec = FFmpeg.avcodec_find_decoder(codecCtx.codec_id);

            if (pCodec == IntPtr.Zero)
            {
                throw new Exception("couldn't find decoder");
            }

            if (FFmpeg.avcodec_open(pCodecCtx, pCodec) < 0)
            {
                throw new Exception("couldn't open codec");
            }

            pFrame    = FFmpeg.avcodec_alloc_frame();
            pFrameRGB = FFmpeg.avcodec_alloc_frame();

            if (pFrameRGB == IntPtr.Zero)
            {
                throw new Exception("couldn't allocate RGB frame");
            }

            int numBytes = FFmpeg.avpicture_get_size(PIXEL_FORMAT, codecCtx.width, codecCtx.height);

            buffer = Marshal.AllocHGlobal(numBytes);

            FFmpeg.avpicture_fill(pFrameRGB, buffer, PIXEL_FORMAT, codecCtx.width, codecCtx.height);

            packet = Marshal.AllocHGlobal(57); // 52 = size of packet struct

            for (int i = 0; i < BufferSize; i++)
            {
                FrameBuffer[i] = new byte[width * height * 4];
            }

            decodingThread = new Thread(Decode);
            decodingThread.IsBackground = true;
            decodingThread.Start();

            return(true);
        }
Example #9
0
        public MediaFile(Stream inStream)
        {
            // Create unique name
            string filename = "stream://" + counter;

            // Register stream
            streams.Add(filename, inStream);

            // Open stream with FFmpeg
            if (FFmpeg.av_open_input_file(out pFormatContext, filename, IntPtr.Zero, 0, IntPtr.Zero) < 0)
            {
                throw new Exception("Unable to open stream");
            }

            // Get context
            FFmpeg.AVFormatContext formatContext = PtrToStructure <FFmpeg.AVFormatContext>(pFormatContext);

            // Get stream info
            if (FFmpeg.av_find_stream_info(pFormatContext) < 0)
            {
                throw new Exception("Unable to find stream info");
            }

            // Loop through streams in this file
            for (int i = 0; i < formatContext.nb_streams; ++i)
            {
                FFmpeg.AVStream       stream       = PtrToStructure <FFmpeg.AVStream>(formatContext.streams[i]);
                FFmpeg.AVCodecContext codecContext = PtrToStructure <FFmpeg.AVCodecContext>(stream.codec);

                // Get codec
                IntPtr         pCodec = FFmpeg.avcodec_find_decoder(codecContext.codec_id);
                FFmpeg.AVCodec codec  = PtrToStructure <FFmpeg.AVCodec>(pCodec);
                if (pCodec == IntPtr.Zero)
                {
                    continue;
                }

                // Check codec type
                bool open = false;
                switch (codecContext.codec_type)
                {
                case FFmpeg.CodecType.CODEC_TYPE_AUDIO:
                    // We only need 1 audio stream
                    if (hasAudio)
                    {
                        break;
                    }

                    // Get stream information
                    hasAudio      = true;
                    numChannels   = codecContext.channels;
                    audioDepth    = (codecContext.sample_fmt == FFmpeg.SampleFormat.SAMPLE_FMT_U8) ? 8 : 16;
                    frequency     = codecContext.sample_rate;
                    audioStream   = stream;
                    audioTimebase = (double)stream.time_base.num / (double)stream.time_base.den;

                    open = true;
                    break;

                case FFmpeg.CodecType.CODEC_TYPE_VIDEO:
                    // We only need 1 video stream
                    if (hasVideo)
                    {
                        break;
                    }

                    // Set codec flags
                    if ((codec.capabilities & FFmpeg.CODEC_CAP_TRUNCATED) != 0)
                    {
                        codecContext.flags = codecContext.flags | FFmpeg.CODEC_FLAG_TRUNCATED;
                    }

                    // Get stream information
                    hasVideo            = true;
                    width               = codecContext.width;
                    height              = codecContext.height;
                    videoStream         = stream;
                    originalVideoFormat = codecContext.pix_fmt;
                    videoTimebase       = (double)codecContext.time_base.num / (double)codecContext.time_base.den;

                    open = true;
                    break;
                }

                // Update codec context
                Marshal.StructureToPtr(codecContext, stream.codec, false);

                // Open codec
                if (open)
                {
                    if (FFmpeg.avcodec_open(stream.codec, pCodec) < 0)
                    {
                        throw new Exception("Unable to open codec");
                    }
                }
            }

            // No video or audio found
            if (!hasAudio && !hasVideo)
            {
                throw new Exception("No codecs or streams found");
            }
        }