Skip to content

Commit

Permalink
feat: add avformat and avdictionary wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
nidbCN committed Dec 30, 2024
1 parent f4ab411 commit 3264cf4
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
78 changes: 78 additions & 0 deletions FfMpegLib.Net/DataStructs/AvDictionaryWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System.Runtime.InteropServices;
using FFmpeg.AutoGen.Abstractions;
using FfMpeg.AutoGen.Wrapper.Extensions;

namespace FfMpeg.AutoGen.Wrapper.DataStructs;

public class AvDictionaryWrapper : WrapperBase<AVDictionary>
{
public string this[string key]
{
get => GetValue(key);
// ReSharper disable once NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract
set => SetValue(key, value ?? string.Empty);
}

public string GetValue(string key, AvDictionaryFlag flag = DefaultFlag)
{
var val = GetValueCore(key, flag);
if (val is null)
throw new ArgumentOutOfRangeException(nameof(key));

return val;
}

public bool TryGetValue(string key, out string? val, AvDictionaryFlag flag = DefaultFlag)
{
val = GetValueCore(key, flag);
return val is not null;
}

private string? GetValueCore(string key, AvDictionaryFlag flag = DefaultFlag)
{
unsafe
{
var entry = ffmpeg.av_dict_get(UnmanagedPointer, key, null, (int)flag);
return entry is null
? null
: Marshal.PtrToStringAuto((IntPtr)entry->value);
}
}

public void SetValue(string key, string value, AvDictionaryFlag flag = DefaultFlag)
=> SetValueCore(key, value, flag).ThrowExceptionIfError();

public bool TrySetValue(string key, string value, AvDictionaryFlag flag = DefaultFlag)
=> SetValueCore(key, value, flag) >= 0;

private int SetValueCore(string key, string? value, AvDictionaryFlag flag = DefaultFlag)
{
unsafe
{
var ptr = UnmanagedPointer;
return ffmpeg.av_dict_set(&ptr, key, value, (int)flag);
}
}

public void Remove(string key, AvDictionaryFlag flag = DefaultFlag)
=> SetValueCore(key, null, flag)
.ThrowExceptionIfError();

public bool TryRemove(string key, AvDictionaryFlag flag = DefaultFlag)
=> SetValueCore(key, null, flag) >= 0;

private const AvDictionaryFlag DefaultFlag = AvDictionaryFlag.MatchCase;
}

[Flags]
public enum AvDictionaryFlag
{
None = 0x00,
MatchCase = ffmpeg.AV_DICT_MATCH_CASE,
IgnoreSuffix = ffmpeg.AV_DICT_IGNORE_SUFFIX,
DoNotStrDupKey = ffmpeg.AV_DICT_DONT_STRDUP_KEY,
DoNotStrDupVal = ffmpeg.AV_DICT_DONT_STRDUP_VAL,
DoNotOverwrite = ffmpeg.AV_DICT_DONT_OVERWRITE,
Append = ffmpeg.AV_DICT_APPEND,
MultiKey = ffmpeg.AV_DICT_MULTIKEY
}
70 changes: 70 additions & 0 deletions FfMpegLib.Net/DataStructs/AvFormatContextWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using FFmpeg.AutoGen.Abstractions;
using FfMpeg.AutoGen.Wrapper.Extensions;

namespace FfMpeg.AutoGen.Wrapper.DataStructs;

public class AvFormatContextWrapper : WrapperBase<AVFormatContext>
{
public unsafe AvFormatContextWrapper()
: base(ffmpeg.avformat_alloc_context()) { }

public unsafe AvFormatContextWrapper(AVFormatContext* context)
: base(context) { }

public bool IsOpen { get; set; }

public unsafe void Open(string url, AVInputFormat* format, AVDictionary* option)
=> OpenCore(url, format, option).ThrowExceptionIfError();

public unsafe bool TryOpen(string url, AVInputFormat* format, AVDictionary* option)
=> OpenCore(url, format, option) == 0;

private unsafe int OpenCore(string url, AVInputFormat* format, AVDictionary* option)
{
var formatCtx = UnmanagedPointer;

var result = ffmpeg.avformat_open_input(&formatCtx, url, format, &option);
IsOpen = result == 0;
return result;
}

public void Close()
{
if (IsOpen)
{
unsafe
{
var formatCtx = UnmanagedPointer;
ffmpeg.avformat_close_input(&formatCtx);
}
}
}

public unsafe bool TryFindStreamInfo(AVDictionary* option = null)
=> FindStreamInfoCore(option) >= 0;

public unsafe void FindStreamInfo(AVDictionary* option = null)
=> FindStreamInfoCore(option).ThrowExceptionIfError();

private unsafe int FindStreamInfoCore(AVDictionary* option)

Check failure on line 49 in FfMpegLib.Net/DataStructs/AvFormatContextWrapper.cs

View workflow job for this annotation

GitHub Actions / build

'AvFormatContextWrapper.FindStreamInfoCore(AVDictionary*)': not all code paths return a value

Check failure on line 49 in FfMpegLib.Net/DataStructs/AvFormatContextWrapper.cs

View workflow job for this annotation

GitHub Actions / build

'AvFormatContextWrapper.FindStreamInfoCore(AVDictionary*)': not all code paths return a value
{
ffmpeg.avformat_find_stream_info(UnmanagedPointer, &option)
.ThrowExceptionIfError();
}

public override void Dispose()
{
unsafe
{
if (!IsOpen)
{
var formatCtx = UnmanagedPointer;
ffmpeg.avformat_close_input(&formatCtx);
}

ffmpeg.avformat_free_context(UnmanagedPointer);
}

GC.SuppressFinalize(this);
}
}

0 comments on commit 3264cf4

Please sign in to comment.