예제 #1
0
        private readonly Stream stream;     // The underlying stream

        /// <summary>
        /// Initializes the structure with the appropriate delegates for
        /// a stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        public StreamDelegates(Stream stream)
        {
            this.stream      = stream;
            this.SetPos32    = new SetStreamPos32Delegate(SetPos32Handler);
            this.GetPos32    = new GetStreamPos32Delegate(GetPos32Handler);
            this.SetPos64    = new SetStreamPos64Delegate(SetPos64Handler);
            this.GetPos64    = new GetStreamPos64Delegate(GetPos64Handler);
            this.Write       = new WriteStreamDelegate(WriteHandler);
            this.Read        = new ReadStreamDelegate(ReadHandler);
            this.GetLength32 = new GetStreamLength32Delegate(GetLength32Handler);
            this.SetLength32 = new SetStreamLength32Delegate(SetLength32Handler);
            this.GetLength64 = new GetStreamLength64Delegate(GetLength64Handler);
            this.SetLength64 = new SetStreamLength64Delegate(SetLength64Handler);
        }
예제 #2
0
        private void OpenInput()
        {
            formatContext = ffmpeg.avformat_alloc_context();
            fixed(AVFormatContext **formatContextPtr = &formatContext)
            {
                int            error;
                AVInputFormat *inputFormat = null;

                if (stream != null)
                {
                    const int bufferSize = 8192;

                    // with delegates and anonymous functions, we can capture
                    // the local stream variable without passing it as a argument.

                    ReadStreamDelegate readStream = (IntPtr opaque, IntPtr buf, int buf_size) =>
                    {
                        byte[] array = new byte[buf_size];

                        int read = stream.Read(array, 0, buf_size);
                        Marshal.Copy(array, 0, buf, read);

                        return(read);
                    };

                    SeekStreamDelegate seekStream = (IntPtr opaque, Int64 offset, int whence) =>
                    {
                        if (whence == ffmpeg.AVSEEK_SIZE)
                        {
                            return(stream.Length);
                        }

                        if (!stream.CanSeek)
                        {
                            return(-1);
                        }

                        stream.Seek(offset, (SeekOrigin)whence);
                        return(stream.Position);
                    };

                    // track the delegates, GC might remove them prematurely
                    delegateRefs.Add(readStream);
                    delegateRefs.Add(seekStream);

                    // setup custom stream reader for ffmpeg to use with AVIO context
                    sbyte *readBuffer = (sbyte *)ffmpeg.av_malloc(bufferSize + ffmpeg.FF_INPUT_BUFFER_PADDING_SIZE);
                    avioContext = ffmpeg.avio_alloc_context(readBuffer, bufferSize, 0, null,
                                                            Marshal.GetFunctionPointerForDelegate(readStream), IntPtr.Zero,
                                                            Marshal.GetFunctionPointerForDelegate(seekStream));

                    formatContext->pb     = avioContext;
                    formatContext->flags |= ffmpeg.AVFMT_FLAG_CUSTOM_IO;

                    if ((error = ffmpeg.av_probe_input_buffer(formatContext->pb, &inputFormat, path, null, 0, 0)) != 0)
                    {
                        throw new FFmpegException(error);
                    }

                    if (path != null && (inputFormat->flags & ffmpeg.AVFMT_NOFILE) != 0)
                    {
                        // Input format (image2) doesn't support custom AVIOContext,
                        // forcefully clear the flag and hope it works.
                        inputFormat->flags &= ~ffmpeg.AVFMT_NOFILE;

                        //ffmpeg.avio_close(formatContext->pb);
                    }
                }

                if ((error = ffmpeg.avformat_open_input(formatContextPtr, path, inputFormat, null)) != 0)
                {
                    throw new FFmpegException(error, "Failed to open input stream for file '" + path + "'");
                }
            }

            frame = ffmpeg.av_frame_alloc();
        }