public MediaStream(Stream baseStream, bool write = false, AVOutputFormat *outputFormat = null) { if (write && !baseStream.CanWrite) { throw new ArgumentException($"流不能被写入,请确保Stream.CanWrite为true"); } if (baseStream.CanRead) { procRead = Read; } if (write && baseStream.CanWrite) { procWrite = Write; } if (baseStream.CanSeek) { procSeek = Seek; } this.baseStream = baseStream; try { formatContext = FF.avformat_alloc_context(); var buffer = (byte *)FF.av_malloc((IntPtr)bufferLength); ioContext = FF.avio_alloc_context(buffer, bufferLength, write, null, procRead, procWrite, procSeek); if (write) { formatContext->Oformat = outputFormat; } formatContext->Pb = ioContext; } catch { Dispose(); throw; } }
public IOContext(Stream stream, bool writable = false) { this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); ulong paddingLength = writable ? 0ul : ffmpeg.AV_INPUT_BUFFER_PADDING_SIZE; // reversed // note: this can be replaced... var buffer = (byte *)ffmpeg.av_malloc(bufferSize + paddingLength); // reference to prevent garbage collection read = Read; write = Write; seek = Seek; Pointer = ffmpeg.avio_alloc_context( buffer: buffer, buffer_size: bufferSize, write_flag: writable ? 1 : 0, opaque: null, read_packet: read, write_packet: write, seek: seek ); Pointer->seekable = ffmpeg.AVIO_SEEKABLE_NORMAL; // | ffmpeg.AVIO_SEEKABLE_TIME; }
public AVIOStream(Stream stream, FileAccess access) { this.stream = stream; Access = access; if (CanRead && !stream.CanRead) { throw new ArgumentException("Can't read from stream"); } if (CanWrite && !stream.CanWrite) { throw new ArgumentException("Can't write to stream"); } byte *ioBuffer = (byte *)ffmpeg.av_malloc(DefaultBufferSize); if (ioBuffer == null) { throw new FFmpegException(ffmpeg.AVERROR(ffmpeg.ENOMEM), "Failed to allocate I/O buffer"); } int writeFlag = 0; avio_alloc_context_read_packet readPacket = null; avio_alloc_context_write_packet writePacket = null; if (CanWrite) { writeFlag = 1; writePacket = WritePacket; writePacketCallbackHandle = GCHandle.Alloc(writePacket); } if (CanRead) { readPacket = ReadPacket; readPacketCallbackHandle = GCHandle.Alloc(readPacket); } ioContext = ffmpeg.avio_alloc_context(ioBuffer, (int)DefaultBufferSize, writeFlag, null, readPacket, writePacket, null); if (ioContext == null) { ffmpeg.av_free(ioBuffer); throw new FFmpegException(ffmpeg.AVERROR(ffmpeg.ENOMEM), "Failed to allocate I/O context"); } }