Skip to content

Commit

Permalink
Introduce BufferRef.
Browse files Browse the repository at this point in the history
  • Loading branch information
sdcb committed Sep 22, 2022
1 parent 1833422 commit 728a90a
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 51 deletions.
18 changes: 17 additions & 1 deletion src/Sdcb.FFmpeg.AutoGen/Gen2/G2Center.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ private static string FormatEscape(string src)
#region codecs
G2TransformDef.MakeClass(ClassCategories.Codecs, "AVPacket", "Packet", new FieldDef[]
{
FieldDef.CreateNullable("side_data")
FieldDef.CreateNullable("side_data"),
FieldDef.CreateNullable("buf"),
FieldDef.CreateNullable("opaque_ref"),
FieldDef.CreateTypeCast("data", TypeCastDef.ReadonlyDataPointer("byte*", "size")) with { ReadOnly = true },
FieldDef.CreateHide("size"),
}),
G2TransformDef.MakeReadonlyStruct(ClassCategories.Codecs, "AVProfile", "MediaProfile", new FieldDef[]
{
Expand Down Expand Up @@ -60,6 +64,8 @@ private static string FormatEscape(string src)
{
FieldDef.CreateNullable("coded_side_data"),
FieldDef.CreateTypeCast("flags", TypeCastDef.Force("int", "AV_CODEC_FLAG")),
FieldDef.CreateNullable("hw_frames_ctx"),
FieldDef.CreateNullable("hw_device_ctx"),
}),
G2TransformDef.MakeClass(ClassCategories.Codecs, "AVCodecParserContext", "CodecParserContext"),
G2TransformDef.MakeStruct(ClassCategories.Codecs, "AVPacketSideData", "PacketSideData", new FieldDef[]
Expand Down Expand Up @@ -130,9 +136,19 @@ private static string FormatEscape(string src)
{
FieldDef.CreateTypeCast("side_data", TypeCastDef.ReadonlyPtrList("AVFrameSideData", "FrameSideData", "nb_side_data", "FromNative")) with { ReadOnly = true },
FieldDef.CreateHide("nb_side_data"),
FieldDef.CreateNullable("hw_frames_ctx"),
FieldDef.CreateNullable("opaque_ref"),
FieldDef.CreateNullable("private_ref"),
}),
G2TransformDef.MakeStruct(ClassCategories.Utils, "AVFrameSideData", "FrameSideData", new FieldDef[]
{
FieldDef.CreateNullable("buf"),
FieldDef.CreateTypeCast("data", TypeCastDef.ReadonlyDataPointer("byte*", "size")) with { ReadOnly = true },
FieldDef.CreateHide("size"),
}),
G2TransformDef.MakeClass(ClassCategories.Utils, "AVBufferRef", "BufferRef", new FieldDef[]
{
FieldDef.CreateTypeCast("buffer", TypeCastDef.Force("AVBuffer*", "IntPtr")),
FieldDef.CreateTypeCast("data", TypeCastDef.ReadonlyDataPointer("byte*", "size")) with { ReadOnly = true },
FieldDef.CreateHide("size"),
}),
Expand Down
14 changes: 8 additions & 6 deletions src/Sdcb.FFmpeg/Codecs/CodecContext.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1470,13 +1470,14 @@ public int NbCodedSideData
}

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <para>A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames. The reference is set by the caller and afterwards owned (and freed) by libavcodec - it should never be read by the caller after being set.</para>
/// <see cref="AVCodecContext.hw_frames_ctx" />
/// </summary>
public AVBufferRef* HwFramesContext
public BufferRef? HwFramesContext
{
get => _ptr->hw_frames_ctx;
set => _ptr->hw_frames_ctx = value;
get => BufferRef.FromNativeOrNull(_ptr->hw_frames_ctx, false);
set => _ptr->hw_frames_ctx = value != null ? (AVBufferRef*)value : null;
}

/// <summary>
Expand Down Expand Up @@ -1510,13 +1511,14 @@ public long MaxPixels
}

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <para>A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/decoder. The reference is set by the caller and afterwards owned (and freed) by libavcodec.</para>
/// <see cref="AVCodecContext.hw_device_ctx" />
/// </summary>
public AVBufferRef* HwDeviceContext
public BufferRef? HwDeviceContext
{
get => _ptr->hw_device_ctx;
set => _ptr->hw_device_ctx = value;
get => BufferRef.FromNativeOrNull(_ptr->hw_device_ctx, false);
set => _ptr->hw_device_ctx = value != null ? (AVBufferRef*)value : null;
}

/// <summary>
Expand Down
2 changes: 0 additions & 2 deletions src/Sdcb.FFmpeg/Codecs/Packet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,6 @@ public void Free()
handle = (IntPtr)ptr;
}

public Span<byte> AsSpan() => new Span<byte>((void*)Data, Size);

/// <summary>
/// <see cref="av_packet_side_data_name(AVPacketSideDataType)"/>
/// </summary>
Expand Down
29 changes: 9 additions & 20 deletions src/Sdcb.FFmpeg/Codecs/Packet.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ protected Packet(AVPacket* ptr, bool isOwner): base(NativeUtils.NotNull((IntPtr)
public override bool IsInvalid => handle == IntPtr.Zero;

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <para>A reference to the reference-counted buffer where the packet data is stored. May be NULL, then the packet data is not reference-counted.</para>
/// <see cref="AVPacket.buf" />
/// </summary>
public AVBufferRef* Buf
public BufferRef? Buf
{
get => _ptr->buf;
set => _ptr->buf = value;
get => BufferRef.FromNativeOrNull(_ptr->buf, false);
set => _ptr->buf = value != null ? (AVBufferRef*)value : null;
}

/// <summary>
Expand All @@ -64,20 +65,7 @@ public long Dts
/// <para>original type: byte*</para>
/// <see cref="AVPacket.data" />
/// </summary>
public IntPtr Data
{
get => (IntPtr)_ptr->data;
set => _ptr->data = (byte*)value;
}

/// <summary>
/// <see cref="AVPacket.size" />
/// </summary>
public int Size
{
get => _ptr->size;
set => _ptr->size = value;
}
public DataPointer Data => new DataPointer(_ptr->data, (int)_ptr->size)!;

/// <summary>
/// <see cref="AVPacket.stream_index" />
Expand Down Expand Up @@ -150,13 +138,14 @@ public IntPtr Opaque
}

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <para>AVBufferRef for free use by the API user. FFmpeg will never check the contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when the packet is unreferenced. av_packet_copy_props() calls create a new reference with av_buffer_ref() for the target packet's opaque_ref field.</para>
/// <see cref="AVPacket.opaque_ref" />
/// </summary>
public AVBufferRef* OpaqueRef
public BufferRef? OpaqueRef
{
get => _ptr->opaque_ref;
set => _ptr->opaque_ref = value;
get => BufferRef.FromNativeOrNull(_ptr->opaque_ref, false);
set => _ptr->opaque_ref = value != null ? (AVBufferRef*)value : null;
}

/// <summary>
Expand Down
11 changes: 2 additions & 9 deletions src/Sdcb.FFmpeg/Common/DataPointer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,7 @@ public DataPointer Slice(int start, int end)
return new DataPointer(Pointer + start, end);
}

public unsafe DataPointer(Span<byte> data)
{
fixed(byte* ptr = data)
{
Pointer = (IntPtr)ptr;
Length = data.Length;
}
}

public unsafe Span<byte> AsSpan() => new Span<byte>((byte*)Pointer, Length);

public byte[] ToArray() => AsSpan().ToArray();
}
2 changes: 1 addition & 1 deletion src/Sdcb.FFmpeg/Sdcb.FFmpeg.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<PackageId>Sdcb.FFmpeg</PackageId>
<VersionPrefix>5.1.1</VersionPrefix>
<VersionSuffix>preview.15</VersionSuffix>
<VersionSuffix>preview.16</VersionSuffix>
<LangVersion>latest</LangVersion>
<!-- Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
<IncludeSymbols>true</IncludeSymbols>
Expand Down
67 changes: 67 additions & 0 deletions src/Sdcb.FFmpeg/Utils/BufferRef.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using Sdcb.FFmpeg.Common;
using Sdcb.FFmpeg.Raw;
using System;
using System.Runtime.InteropServices;
using static Sdcb.FFmpeg.Raw.ffmpeg;

namespace Sdcb.FFmpeg.Utils;

public unsafe partial class BufferRef : SafeHandle
{
/// <summary>Allocate an AVBuffer of the given size using av_malloc().</summary>
public static BufferRef Alloc(int size) => new BufferRef(av_buffer_alloc((ulong)size), isOwner: true);

/// <summary>Same as av_buffer_alloc(), except the returned buffer will be initialized to zero.</summary>
public static BufferRef AllocZ(int size) => new BufferRef(av_buffer_allocz((ulong)size), isOwner: true);

/// <summary>Create a new reference to an AVBuffer.</summary>
public static BufferRef Ref(BufferRef other) => new BufferRef(av_buffer_ref(other), isOwner: true);

/// <summary>Returns 1 if the caller may write to the data referred to by buf (which is true if and only if buf is the only reference to the underlying AVBuffer). Return 0 otherwise. A positive answer is valid until av_buffer_ref() is called on buf.</summary>
public bool IsWritable => av_buffer_is_writable(this) != 0;

/// <summary>Returns the opaque parameter set by av_buffer_create.</summary>
public IntPtr Opaque => (IntPtr)av_buffer_get_opaque(this);

public int RefCount => av_buffer_get_ref_count(this);

/// <summary>Free a given reference and automatically free the buffer if there are no more references to it.</summary>
public void Unref()
{
AVBufferRef* ptr = this;
av_buffer_unref(&ptr);
handle = (IntPtr)ptr;
}

/// <summary>Create a writable reference from a given buffer reference, avoiding data copy if possible.</summary>
public void MakeWritable()
{
AVBufferRef* ptr = this;
av_buffer_make_writable(&ptr).ThrowIfError();
handle = (IntPtr)ptr;
}

/// <summary>Reallocate a given buffer.</summary>
/// <param name="size">required new buffer size.</param>
public void Realloc(int size)
{
AVBufferRef* ptr = this;
av_buffer_realloc(&ptr, (ulong)size).ThrowIfError();
handle = (IntPtr)ptr;
}

/// <summary>Ensure dst refers to the same data as src.</summary>
/// <param name="src">Pointer to either a valid buffer reference or NULL. On success, this will point to a buffer reference equivalent to src. On failure, dst will be left untouched.</param>
public void Replace(BufferRef src)
{
AVBufferRef* ptr = this;
av_buffer_replace(&ptr, src).ThrowIfError();
handle = (IntPtr)ptr;
}

protected override bool ReleaseHandle()
{
Unref();
return true;
}
}
50 changes: 50 additions & 0 deletions src/Sdcb.FFmpeg/Utils/BufferRef.g.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// This file was genereated from Sdcb.FFmpeg.AutoGen, DO NOT CHANGE DIRECTLY.
#nullable enable
using Sdcb.FFmpeg.Common;
using Sdcb.FFmpeg.Codecs;
using Sdcb.FFmpeg.Formats;
using Sdcb.FFmpeg.Raw;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace Sdcb.FFmpeg.Utils;

/// <summary>
/// <para>A reference to a data buffer.</para>
/// <see cref="AVBufferRef" />
/// </summary>
public unsafe partial class BufferRef : SafeHandle
{
protected AVBufferRef* _ptr => (AVBufferRef*)handle;

public static implicit operator AVBufferRef*(BufferRef data) => data != null ? (AVBufferRef*)data.handle : null;

protected BufferRef(AVBufferRef* ptr, bool isOwner): base(NativeUtils.NotNull((IntPtr)ptr), isOwner)
{
}

public static BufferRef FromNative(AVBufferRef* ptr, bool isOwner) => new BufferRef(ptr, isOwner);

public static BufferRef? FromNativeOrNull(AVBufferRef* ptr, bool isOwner) => ptr == null ? null : new BufferRef(ptr, isOwner);

public override bool IsInvalid => handle == IntPtr.Zero;

/// <summary>
/// <para>original type: AVBuffer*</para>
/// <see cref="AVBufferRef.buffer" />
/// </summary>
public IntPtr Buffer
{
get => (IntPtr)_ptr->buffer;
set => _ptr->buffer = (AVBuffer*)value;
}

/// <summary>
/// <para>original type: byte*</para>
/// <para>The data buffer. It is considered writable if and only if this is the only reference to the buffer, in which case av_buffer_is_writable() returns 1.</para>
/// <see cref="AVBufferRef.data" />
/// </summary>
public DataPointer Data => new DataPointer(_ptr->data, (int)_ptr->size)!;

}
21 changes: 12 additions & 9 deletions src/Sdcb.FFmpeg/Utils/Frame.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,23 +438,25 @@ public int PktSize
}

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <para>For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.</para>
/// <see cref="AVFrame.hw_frames_ctx" />
/// </summary>
public AVBufferRef* HwFramesContext
public BufferRef? HwFramesContext
{
get => _ptr->hw_frames_ctx;
set => _ptr->hw_frames_ctx = value;
get => BufferRef.FromNativeOrNull(_ptr->hw_frames_ctx, false);
set => _ptr->hw_frames_ctx = value != null ? (AVBufferRef*)value : null;
}

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <para>AVBufferRef for free use by the API user. FFmpeg will never check the contents of the buffer ref. FFmpeg calls av_buffer_unref() on it when the frame is unreferenced. av_frame_copy_props() calls create a new reference with av_buffer_ref() for the target frame's opaque_ref field.</para>
/// <see cref="AVFrame.opaque_ref" />
/// </summary>
public AVBufferRef* OpaqueRef
public BufferRef? OpaqueRef
{
get => _ptr->opaque_ref;
set => _ptr->opaque_ref = value;
get => BufferRef.FromNativeOrNull(_ptr->opaque_ref, false);
set => _ptr->opaque_ref = value != null ? (AVBufferRef*)value : null;
}

/// <summary>
Expand Down Expand Up @@ -495,13 +497,14 @@ public ulong CropRight
}

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <para>AVBufferRef for internal use by a single libav* library. Must not be used to transfer data between libraries. Has to be NULL when ownership of the frame leaves the respective library.</para>
/// <see cref="AVFrame.private_ref" />
/// </summary>
public AVBufferRef* PrivateRef
public BufferRef? PrivateRef
{
get => _ptr->private_ref;
set => _ptr->private_ref = value;
get => BufferRef.FromNativeOrNull(_ptr->private_ref, false);
set => _ptr->private_ref = value != null ? (AVBufferRef*)value : null;
}

/// <summary>
Expand Down
7 changes: 4 additions & 3 deletions src/Sdcb.FFmpeg/Utils/FrameSideData.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ public MediaDictionary Metadata
}

/// <summary>
/// <para>original type: AVBufferRef*</para>
/// <see cref="AVFrameSideData.buf" />
/// </summary>
public AVBufferRef* Buf
public BufferRef? Buf
{
get => _ptr->buf;
set => _ptr->buf = value;
get => BufferRef.FromNativeOrNull(_ptr->buf, false);
set => _ptr->buf = value != null ? (AVBufferRef*)value : null;
}
}

0 comments on commit 728a90a

Please sign in to comment.