Skip to content

Commit 3e9d93f

Browse files
committed
added an additional example that can be used with DllImport on .NET Core
1 parent e8bcc13 commit 3e9d93f

11 files changed

+766
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,5 @@
2626
/source/ffmpeg-cpp/difference/obj
2727
/source/ffmpeg-cpp/print_info/obj/x64
2828
/source/ffmpeg-cpp/filtering_audio/obj/x64
29+
/source/ffmpeg-cpp/simple_interface/x64/Debug
30+
/source/ffmpeg-cpp/simple_interface_demo/obj/x64

source/ffmpeg-cpp/ffmpeg-cpp.sln

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "print_info", "print_info\pr
2727
EndProject
2828
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filtering_audio", "filtering_audio\filtering_audio.vcxproj", "{220FA552-86EF-4437-867D-AB34F7285F8B}"
2929
EndProject
30+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_interface", "simple_interface\simple_interface.vcxproj", "{E5D40BD4-7158-4182-8985-9400FAEEC2DB}"
31+
EndProject
32+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_interface_demo", "simple_interface_demo\simple_interface_demo.vcxproj", "{5CAFFF39-CD0E-4D6D-8E68-246562914788}"
33+
EndProject
3034
Global
3135
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3236
Debug|x64 = Debug|x64
@@ -353,6 +357,62 @@ Global
353357
{220FA552-86EF-4437-867D-AB34F7285F8B}.ReleaseLTO|x64.Build.0 = Release|x64
354358
{220FA552-86EF-4437-867D-AB34F7285F8B}.ReleaseLTO|x86.ActiveCfg = Release|Win32
355359
{220FA552-86EF-4437-867D-AB34F7285F8B}.ReleaseLTO|x86.Build.0 = Release|Win32
360+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Debug|x64.ActiveCfg = Debug|x64
361+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Debug|x64.Build.0 = Debug|x64
362+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Debug|x86.ActiveCfg = Debug|Win32
363+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Debug|x86.Build.0 = Debug|Win32
364+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLL|x64.ActiveCfg = Debug|x64
365+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLL|x64.Build.0 = Debug|x64
366+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLL|x86.ActiveCfg = Debug|Win32
367+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLL|x86.Build.0 = Debug|Win32
368+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
369+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
370+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
371+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
372+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Release|x64.ActiveCfg = Release|x64
373+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Release|x64.Build.0 = Release|x64
374+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Release|x86.ActiveCfg = Release|Win32
375+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.Release|x86.Build.0 = Release|Win32
376+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLL|x64.ActiveCfg = Release|x64
377+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLL|x64.Build.0 = Release|x64
378+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLL|x86.ActiveCfg = Release|Win32
379+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLL|x86.Build.0 = Release|Win32
380+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
381+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
382+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
383+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
384+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseLTO|x64.ActiveCfg = Release|x64
385+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseLTO|x64.Build.0 = Release|x64
386+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseLTO|x86.ActiveCfg = Release|Win32
387+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB}.ReleaseLTO|x86.Build.0 = Release|Win32
388+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Debug|x64.ActiveCfg = Debug|x64
389+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Debug|x64.Build.0 = Debug|x64
390+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Debug|x86.ActiveCfg = Debug|Win32
391+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Debug|x86.Build.0 = Debug|Win32
392+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLL|x64.ActiveCfg = Debug|x64
393+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLL|x64.Build.0 = Debug|x64
394+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLL|x86.ActiveCfg = Debug|Win32
395+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLL|x86.Build.0 = Debug|Win32
396+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLLStaticDeps|x64.ActiveCfg = Debug|x64
397+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLLStaticDeps|x64.Build.0 = Debug|x64
398+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLLStaticDeps|x86.ActiveCfg = Debug|Win32
399+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.DebugDLLStaticDeps|x86.Build.0 = Debug|Win32
400+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Release|x64.ActiveCfg = Release|x64
401+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Release|x64.Build.0 = Release|x64
402+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Release|x86.ActiveCfg = Release|Win32
403+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.Release|x86.Build.0 = Release|Win32
404+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLL|x64.ActiveCfg = Release|x64
405+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLL|x64.Build.0 = Release|x64
406+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLL|x86.ActiveCfg = Release|Win32
407+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLL|x86.Build.0 = Release|Win32
408+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLLStaticDeps|x64.ActiveCfg = Release|x64
409+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLLStaticDeps|x64.Build.0 = Release|x64
410+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLLStaticDeps|x86.ActiveCfg = Release|Win32
411+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseDLLStaticDeps|x86.Build.0 = Release|Win32
412+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseLTO|x64.ActiveCfg = Release|x64
413+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseLTO|x64.Build.0 = Release|x64
414+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseLTO|x86.ActiveCfg = Release|Win32
415+
{5CAFFF39-CD0E-4D6D-8E68-246562914788}.ReleaseLTO|x86.Build.0 = Release|Win32
356416
EndGlobalSection
357417
GlobalSection(SolutionProperties) = preSolution
358418
HideSolutionNode = FALSE
@@ -367,6 +427,8 @@ Global
367427
{9BD8FF1D-1C1B-4755-BF5C-AD58DC023711} = {3B1FE419-D7D2-4406-9C24-5A6F6ED63E73}
368428
{B4DB4D63-7AD7-42B9-9671-AD39D696B4FF} = {3B1FE419-D7D2-4406-9C24-5A6F6ED63E73}
369429
{220FA552-86EF-4437-867D-AB34F7285F8B} = {3B1FE419-D7D2-4406-9C24-5A6F6ED63E73}
430+
{E5D40BD4-7158-4182-8985-9400FAEEC2DB} = {3B1FE419-D7D2-4406-9C24-5A6F6ED63E73}
431+
{5CAFFF39-CD0E-4D6D-8E68-246562914788} = {3B1FE419-D7D2-4406-9C24-5A6F6ED63E73}
370432
EndGlobalSection
371433
GlobalSection(ExtensibilityGlobals) = postSolution
372434
SolutionGuid = {1838F09B-B929-4D1E-ABB6-FA2A94F4A4BE}
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
// AniHub.LipSync.cpp : Defines the exported functions for the DLL application.
2+
//
3+
4+
#include "SimpleInterface.h"
5+
6+
#include <string>
7+
#include <iostream>
8+
#include <stdio.h>
9+
#include <io.h>
10+
#include <filesystem>
11+
#include <fstream>
12+
#include <sstream>
13+
14+
#include "ffmpegcpp.h"
15+
#include "ffmpeg.h"
16+
17+
using namespace std;
18+
using namespace ffmpegcpp;
19+
20+
21+
struct Context
22+
{
23+
Muxer* muxer = nullptr;
24+
25+
VideoCodec* videoCodec = nullptr;
26+
AudioCodec* audioCodec = nullptr;
27+
28+
Demuxer* videoDemuxer = nullptr;
29+
Demuxer* audioDemuxer = nullptr;
30+
31+
const char* videoFilterString = nullptr;
32+
const char* audioFilterString = nullptr;
33+
34+
Filter* videoFilter = nullptr;
35+
Filter* audioFilter = nullptr;
36+
37+
VideoFrameSink* videoEncoder = nullptr;
38+
AudioFrameSink* audioEncoder = nullptr;
39+
40+
RawVideoDataSource* source = nullptr;
41+
42+
vector<Demuxer*> uniqueDemuxers;
43+
44+
bool errored = false;
45+
string error;
46+
};
47+
48+
void SetError(Context* ctx, string error)
49+
{
50+
ctx->errored = true;
51+
ctx->error = string(error);
52+
}
53+
54+
void CleanUp(Context* ctx)
55+
{
56+
if (ctx->muxer != nullptr) delete ctx->muxer;
57+
58+
if (ctx->videoEncoder != nullptr) delete ctx->videoEncoder;
59+
if (ctx->audioEncoder != nullptr) delete ctx->audioEncoder;
60+
61+
if (ctx->videoFilter != nullptr) delete ctx->videoFilter;
62+
if (ctx->audioFilter != nullptr) delete ctx->audioFilter;
63+
64+
if (ctx->videoCodec != nullptr) delete ctx->videoCodec;
65+
if (ctx->audioCodec != nullptr) delete ctx->audioCodec;
66+
67+
for (int i = 0; i < ctx->uniqueDemuxers.size(); ++i)
68+
{
69+
delete ctx->uniqueDemuxers[i];
70+
}
71+
72+
delete ctx;
73+
}
74+
75+
Demuxer* GetExistingDemuxer(Context* ctx, const char* fileName)
76+
{
77+
if (ctx->videoDemuxer != nullptr && string(ctx->videoDemuxer->GetFileName()) == string(fileName)) return ctx->videoDemuxer;
78+
if (ctx->audioDemuxer != nullptr && string(ctx->audioDemuxer->GetFileName()) == string(fileName)) return ctx->audioDemuxer;
79+
return nullptr;
80+
}
81+
82+
void* ffmpegCppCreate(const char* outputFileName)
83+
{
84+
Context* ctx = new Context();
85+
try
86+
{
87+
// create the output muxer but don't add any streams yet
88+
ctx->muxer = new Muxer(outputFileName);
89+
return ctx;
90+
}
91+
catch (FFmpegException e)
92+
{
93+
SetError(ctx, string("Failed to create output file " + string(outputFileName) + ": " + string(e.what())));
94+
return nullptr;
95+
}
96+
}
97+
98+
void ffmpegCppAddVideoStream(void* handle, const char* videoFileName)
99+
{
100+
Context* ctx = (Context*)handle;
101+
try
102+
{
103+
// create the demuxer or re-use the previous one
104+
ctx->videoDemuxer = GetExistingDemuxer(ctx, videoFileName);
105+
if (ctx->videoDemuxer == nullptr)
106+
{
107+
ctx->videoDemuxer = new Demuxer(videoFileName);
108+
ctx->uniqueDemuxers.push_back(ctx->videoDemuxer);
109+
}
110+
111+
// create the encoder
112+
ctx->videoCodec = new VideoCodec(ctx->muxer->GetDefaultVideoFormat()->id);
113+
ctx->videoEncoder = new VideoEncoder(ctx->videoCodec, ctx->muxer);
114+
}
115+
catch (FFmpegException e)
116+
{
117+
SetError(ctx, string("Failed to add video stream " + string(videoFileName) + ": " + string(e.what())));
118+
}
119+
}
120+
121+
void ffmpegCppAddAudioStream(void* handle, const char* audioFileName)
122+
{
123+
Context* ctx = (Context*)handle;
124+
try
125+
{
126+
// create the demuxer or re-use the previous one
127+
ctx->audioDemuxer = GetExistingDemuxer(ctx, audioFileName);
128+
if (ctx->audioDemuxer == nullptr)
129+
{
130+
ctx->audioDemuxer = new Demuxer(audioFileName);
131+
ctx->uniqueDemuxers.push_back(ctx->audioDemuxer);
132+
}
133+
134+
// create the encoder
135+
ctx->audioCodec = new AudioCodec(ctx->muxer->GetDefaultAudioFormat()->id);
136+
ctx->audioEncoder = new AudioEncoder(ctx->audioCodec, ctx->muxer);
137+
}
138+
catch (FFmpegException e)
139+
{
140+
SetError(ctx, string("Failed to add audio stream " + string(audioFileName) + ": " + string(e.what())));
141+
}
142+
}
143+
144+
void ffmpegCppAddVideoFilter(void* handle, const char* filterString)
145+
{
146+
Context* ctx = (Context*)handle;
147+
ctx->videoFilterString = filterString;
148+
}
149+
150+
void ffmpegCppAddAudioFilter(void* handle, const char* filterString)
151+
{
152+
Context* ctx = (Context*)handle;
153+
ctx->audioFilterString = filterString;
154+
}
155+
156+
void ffmpegCppGenerate(void* handle)
157+
{
158+
Context* ctx = (Context*)handle;
159+
try
160+
{
161+
// create a filter if necessary
162+
FrameSink* videoFrameSink = ctx->videoEncoder;
163+
FrameSink* audioFrameSink = ctx->audioEncoder;
164+
if (ctx->videoFilterString != nullptr)
165+
{
166+
ctx->videoFilter = new Filter(ctx->videoFilterString, ctx->videoEncoder);
167+
videoFrameSink = ctx->videoFilter;
168+
}
169+
if (ctx->audioFilterString != nullptr)
170+
{
171+
ctx->audioFilter = new Filter(ctx->audioFilterString, ctx->audioEncoder);
172+
audioFrameSink = ctx->audioFilter;
173+
}
174+
175+
// connect the input and output streams
176+
if (ctx->videoDemuxer != nullptr)
177+
{
178+
ctx->videoDemuxer->DecodeBestVideoStream(videoFrameSink);
179+
}
180+
if (ctx->audioDemuxer != nullptr)
181+
{
182+
ctx->audioDemuxer->DecodeBestAudioStream(audioFrameSink);
183+
}
184+
185+
// now go over all the streams and process all frames
186+
for (int i = 0; i < ctx->uniqueDemuxers.size(); ++i)
187+
{
188+
ctx->uniqueDemuxers[i]->PreparePipeline();
189+
}
190+
191+
// finally, we can start writing data to our pipelines. Open the floodgates
192+
// to start reading frames from the input, decoding them, optionally filtering them,
193+
// encoding them and writing them to the final container.
194+
// This can be interweaved if you want to.
195+
for (int i = 0; i < ctx->uniqueDemuxers.size(); ++i)
196+
{
197+
Demuxer* demuxer = ctx->uniqueDemuxers[i];
198+
while (!demuxer->IsDone()) demuxer->Step();
199+
}
200+
201+
// close the muxer and save the file to disk
202+
ctx->muxer->Close();
203+
}
204+
catch (FFmpegException e)
205+
{
206+
SetError(ctx, string("Failed to generate output file: " + string(e.what())));
207+
}
208+
}
209+
210+
void ffmpegCppAddFilter(void* handle, const char* filterString)
211+
{
212+
// TODO
213+
}
214+
215+
216+
bool ffmpegCppIsError(void* handle)
217+
{
218+
return ((Context*)handle)->errored;
219+
}
220+
221+
const char* ffmpegCppGetError(void* handle)
222+
{
223+
return ((Context*)handle)->error.c_str();
224+
}
225+
226+
void ffmpegCppClose(void* handle)
227+
{
228+
CleanUp((Context*)handle);
229+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// MathLibrary.h - Contains declarations of math functions
2+
#pragma once
3+
4+
#define DllExport __declspec(dllexport)
5+
6+
7+
extern "C" DllExport void* ffmpegCppCreate(const char* outputFileName);
8+
9+
extern "C" DllExport void ffmpegCppAddVideoStream(void* handle, const char* videoFileName);
10+
extern "C" DllExport void ffmpegCppAddAudioStream(void* handle, const char* audioFileName);
11+
12+
extern "C" DllExport void ffmpegCppAddVideoFilter(void* handle, const char* filterString);
13+
extern "C" DllExport void ffmpegCppAddAudioFilter(void* handle, const char* filterString);
14+
15+
extern "C" DllExport void ffmpegCppGenerate(void* handle);
16+
17+
extern "C" DllExport bool ffmpegCppIsError(void* handle);
18+
extern "C" DllExport const char* ffmpegCppGetError(void* handle);
19+
20+
extern "C" DllExport void ffmpegCppClose(void* handle);

0 commit comments

Comments
 (0)