Skip to content

Instantly share code, notes, and snippets.

@brianmed
Created December 18, 2022 02:39
Show Gist options
  • Save brianmed/ead2d7e116c4cc92de06d549d33f66f4 to your computer and use it in GitHub Desktop.
Save brianmed/ead2d7e116c4cc92de06d549d33f66f4 to your computer and use it in GitHub Desktop.
Small Program that Outputs Number of Streams in a Container via FFmpeg
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FFmpeg.AutoGen" Version="4.4.1.1" />
<PackageReference Include="FFmpeg.AutoGen.Abstractions" Version="4.3.2" />
<PackageReference Include="FFmpeg.AutoGen.Bindings.DynamicallyLoaded" Version="4.3.2" />
<PackageReference Include="System.CommandLine.DragonFruit" Version="0.4.0-alpha.22272.1" />
</ItemGroup>
</Project>
using System;
using System.Runtime.InteropServices;
// using FFmpeg.AutoGen;
using FFmpeg.AutoGen.Abstractions;
using FFmpeg.AutoGen.Bindings.DynamicallyLoaded;
namespace FFmpegProbePackets;
unsafe class Program
{
struct AVIOOpaqueInput
{
public IntPtr InputData;
public uint RemainingBytes;
public long Idx;
public uint TotalSize;
};
static AVFormatContext *avFormatContext = null;
static void Main(string containerFile, bool useBuffer)
{
Console.WriteLine("Running in {0}-bit mode.", Environment.Is64BitProcess ? "64" : "32");
DynamicallyLoadedBindings.Initialize();
Console.WriteLine($"FFmpeg version info: {ffmpeg.av_version_info()}");
avFormatContext = ffmpeg.avformat_alloc_context();
Console.WriteLine(avFormatContext->nb_streams);
if (useBuffer)
{
readBuffer(containerFile);
}
else
{
readFile(containerFile);
}
Console.WriteLine("joy");
Console.WriteLine(avFormatContext->nb_streams);
}
static void readBuffer(string filename)
{
AVIOOpaqueInput opaqueInput = new();
AVIOContext *avioContext = null;
byte[] bytes = System.IO.File.ReadAllBytes(filename);
fixed (byte *bytesPtr = bytes)
fixed (AVFormatContext **avFormatContextPtr = &avFormatContext)
{
opaqueInput.InputData = new IntPtr(bytesPtr);
opaqueInput.RemainingBytes = (uint)bytes.Length;
opaqueInput.Idx = 0;
opaqueInput.TotalSize = (uint)bytes.Length;
void *opaqueInputPtr = &opaqueInput;
IntPtr opaqueInputIntPtr = new IntPtr(opaqueInputPtr);
avio_alloc_context_read_packet readStream = (void *opaque, byte *buf, int buf_size) =>
{
return readPacketStatic(opaque, buf, buf_size);
};
avioContext = ffmpeg
.avio_alloc_context(
bytesPtr, bytes.Length,
0,
opaqueInputIntPtr.ToPointer(),
readStream, null, null);
avFormatContext->pb = avioContext;
avFormatContext->probesize = bytes.Length;
ffmpeg
.avformat_open_input(avFormatContextPtr, null, null, null);
}
}
static void readFile(string filename)
{
fixed (AVFormatContext **avFormatContextPtr = &avFormatContext)
{
ffmpeg
.avformat_open_input(avFormatContextPtr, filename, null, null);
}
}
static int readPacketStatic(void *opaque, void *buf, int buf_size)
{
Console.WriteLine($"buf_size: {buf_size}");
int bytes_read = (int)Math.Min(buf_size, ((AVIOOpaqueInput *)opaque)->RemainingBytes);
unsafe
{
Buffer.MemoryCopy(((AVIOOpaqueInput *)opaque)->InputData.ToPointer(), buf, bytes_read, bytes_read);
}
((AVIOOpaqueInput *)opaque)->RemainingBytes -= (uint)bytes_read;
Console.WriteLine($"bytes_read: {bytes_read}: {((AVIOOpaqueInput *)opaque)->RemainingBytes}");
return bytes_read;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment