Skip to content

Commit 46010a8

Browse files
committed
improved the simple-interface system and made it more fool-proof
1 parent 3e9d93f commit 46010a8

File tree

6 files changed

+106
-69
lines changed

6 files changed

+106
-69
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@
2828
/source/ffmpeg-cpp/filtering_audio/obj/x64
2929
/source/ffmpeg-cpp/simple_interface/x64/Debug
3030
/source/ffmpeg-cpp/simple_interface_demo/obj/x64
31+
/source/ffmpeg-cpp/simple_interface/Debug/simple_interface.tlog
32+
/source/ffmpeg-cpp/simple_interface/Debug

source/ffmpeg-cpp/simple_interface/SimpleInterface.cpp

Lines changed: 69 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -18,51 +18,59 @@ using namespace std;
1818
using namespace ffmpegcpp;
1919

2020

21-
struct Context
21+
template<class CodecType, class FrameSinkType>
22+
struct StreamContext
2223
{
23-
Muxer* muxer = nullptr;
24+
CodecType* codec = nullptr;
2425

25-
VideoCodec* videoCodec = nullptr;
26-
AudioCodec* audioCodec = nullptr;
26+
string sourceFileName;
27+
Demuxer* demuxer = nullptr;
2728

28-
Demuxer* videoDemuxer = nullptr;
29-
Demuxer* audioDemuxer = nullptr;
29+
bool hasFilter = false;
30+
string filterString;
31+
Filter* filter = nullptr;
3032

31-
const char* videoFilterString = nullptr;
32-
const char* audioFilterString = nullptr;
33+
FrameSinkType* encoder = nullptr;
3334

34-
Filter* videoFilter = nullptr;
35-
Filter* audioFilter = nullptr;
35+
void CleanUp()
36+
{
37+
if (encoder != nullptr) delete encoder;
38+
if (filter != nullptr) delete filter;
39+
if (codec != nullptr) delete codec;
40+
// the demuxer can be shared amongst different contexts, so we don't delete them here
41+
}
42+
};
3643

37-
VideoFrameSink* videoEncoder = nullptr;
38-
AudioFrameSink* audioEncoder = nullptr;
44+
struct Context
45+
{
46+
string outputFileName;
47+
Muxer* muxer = nullptr;
3948

40-
RawVideoDataSource* source = nullptr;
49+
StreamContext<VideoCodec, VideoFrameSink> videoContext;
50+
StreamContext<AudioCodec, AudioFrameSink> audioContext;
4151

4252
vector<Demuxer*> uniqueDemuxers;
4353

4454
bool errored = false;
45-
string error;
55+
char* error;
4656
};
4757

4858
void SetError(Context* ctx, string error)
4959
{
5060
ctx->errored = true;
51-
ctx->error = string(error);
61+
string err = string(error);
62+
ctx->error = new char[err.length() + 1];
63+
strcpy(ctx->error, err.c_str());
5264
}
5365

5466
void CleanUp(Context* ctx)
5567
{
5668
if (ctx->muxer != nullptr) delete ctx->muxer;
5769

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;
70+
ctx->videoContext.CleanUp();
71+
ctx->audioContext.CleanUp();
6372

64-
if (ctx->videoCodec != nullptr) delete ctx->videoCodec;
65-
if (ctx->audioCodec != nullptr) delete ctx->audioCodec;
73+
if (ctx->error != nullptr) delete ctx->error;
6674

6775
for (int i = 0; i < ctx->uniqueDemuxers.size(); ++i)
6876
{
@@ -74,8 +82,10 @@ void CleanUp(Context* ctx)
7482

7583
Demuxer* GetExistingDemuxer(Context* ctx, const char* fileName)
7684
{
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;
85+
for (int i = 0; i < ctx->uniqueDemuxers.size(); ++i)
86+
{
87+
if (string(ctx->uniqueDemuxers[i]->GetFileName()) == string(fileName)) return ctx->uniqueDemuxers[i];
88+
}
7989
return nullptr;
8090
}
8191

@@ -85,12 +95,13 @@ void* ffmpegCppCreate(const char* outputFileName)
8595
try
8696
{
8797
// create the output muxer but don't add any streams yet
88-
ctx->muxer = new Muxer(outputFileName);
98+
ctx->outputFileName = string(outputFileName);
99+
ctx->muxer = new Muxer(ctx->outputFileName.c_str());
89100
return ctx;
90101
}
91102
catch (FFmpegException e)
92103
{
93-
SetError(ctx, string("Failed to create output file " + string(outputFileName) + ": " + string(e.what())));
104+
SetError(ctx, string("Failed to create output file " + ctx->outputFileName + ": " + string(e.what())));
94105
return nullptr;
95106
}
96107
}
@@ -101,16 +112,17 @@ void ffmpegCppAddVideoStream(void* handle, const char* videoFileName)
101112
try
102113
{
103114
// create the demuxer or re-use the previous one
104-
ctx->videoDemuxer = GetExistingDemuxer(ctx, videoFileName);
105-
if (ctx->videoDemuxer == nullptr)
115+
ctx->videoContext.sourceFileName = videoFileName;
116+
ctx->videoContext.demuxer = GetExistingDemuxer(ctx, videoFileName);
117+
if (ctx->videoContext.demuxer == nullptr)
106118
{
107-
ctx->videoDemuxer = new Demuxer(videoFileName);
108-
ctx->uniqueDemuxers.push_back(ctx->videoDemuxer);
119+
ctx->videoContext.demuxer = new Demuxer(ctx->videoContext.sourceFileName.c_str());
120+
ctx->uniqueDemuxers.push_back(ctx->videoContext.demuxer);
109121
}
110122

111123
// create the encoder
112-
ctx->videoCodec = new VideoCodec(ctx->muxer->GetDefaultVideoFormat()->id);
113-
ctx->videoEncoder = new VideoEncoder(ctx->videoCodec, ctx->muxer);
124+
ctx->videoContext.codec = new VideoCodec(ctx->muxer->GetDefaultVideoFormat()->id);
125+
ctx->videoContext.encoder = new VideoEncoder(ctx->videoContext.codec, ctx->muxer);
114126
}
115127
catch (FFmpegException e)
116128
{
@@ -124,16 +136,17 @@ void ffmpegCppAddAudioStream(void* handle, const char* audioFileName)
124136
try
125137
{
126138
// create the demuxer or re-use the previous one
127-
ctx->audioDemuxer = GetExistingDemuxer(ctx, audioFileName);
128-
if (ctx->audioDemuxer == nullptr)
139+
ctx->audioContext.sourceFileName = audioFileName;
140+
ctx->audioContext.demuxer = GetExistingDemuxer(ctx, audioFileName);
141+
if (ctx->audioContext.demuxer == nullptr)
129142
{
130-
ctx->audioDemuxer = new Demuxer(audioFileName);
131-
ctx->uniqueDemuxers.push_back(ctx->audioDemuxer);
143+
ctx->audioContext.demuxer = new Demuxer(ctx->audioContext.sourceFileName.c_str());
144+
ctx->uniqueDemuxers.push_back(ctx->audioContext.demuxer);
132145
}
133146

134147
// create the encoder
135-
ctx->audioCodec = new AudioCodec(ctx->muxer->GetDefaultAudioFormat()->id);
136-
ctx->audioEncoder = new AudioEncoder(ctx->audioCodec, ctx->muxer);
148+
ctx->audioContext.codec = new AudioCodec(ctx->muxer->GetDefaultAudioFormat()->id);
149+
ctx->audioContext.encoder = new AudioEncoder(ctx->audioContext.codec, ctx->muxer);
137150
}
138151
catch (FFmpegException e)
139152
{
@@ -144,13 +157,15 @@ void ffmpegCppAddAudioStream(void* handle, const char* audioFileName)
144157
void ffmpegCppAddVideoFilter(void* handle, const char* filterString)
145158
{
146159
Context* ctx = (Context*)handle;
147-
ctx->videoFilterString = filterString;
160+
ctx->videoContext.filterString = filterString;
161+
ctx->videoContext.hasFilter = true;
148162
}
149163

150164
void ffmpegCppAddAudioFilter(void* handle, const char* filterString)
151165
{
152166
Context* ctx = (Context*)handle;
153-
ctx->audioFilterString = filterString;
167+
ctx->audioContext.filterString = filterString;
168+
ctx->audioContext.hasFilter = true;
154169
}
155170

156171
void ffmpegCppGenerate(void* handle)
@@ -159,27 +174,27 @@ void ffmpegCppGenerate(void* handle)
159174
try
160175
{
161176
// create a filter if necessary
162-
FrameSink* videoFrameSink = ctx->videoEncoder;
163-
FrameSink* audioFrameSink = ctx->audioEncoder;
164-
if (ctx->videoFilterString != nullptr)
177+
FrameSink* videoFrameSink = ctx->videoContext.encoder;
178+
FrameSink* audioFrameSink = ctx->audioContext.encoder;
179+
if (ctx->videoContext.hasFilter)
165180
{
166-
ctx->videoFilter = new Filter(ctx->videoFilterString, ctx->videoEncoder);
167-
videoFrameSink = ctx->videoFilter;
181+
ctx->videoContext.filter = new Filter(ctx->videoContext.filterString.c_str(), videoFrameSink);
182+
videoFrameSink = ctx->videoContext.filter;
168183
}
169-
if (ctx->audioFilterString != nullptr)
184+
if (ctx->audioContext.hasFilter)
170185
{
171-
ctx->audioFilter = new Filter(ctx->audioFilterString, ctx->audioEncoder);
172-
audioFrameSink = ctx->audioFilter;
186+
ctx->audioContext.filter = new Filter(ctx->audioContext.filterString.c_str(), audioFrameSink);
187+
audioFrameSink = ctx->audioContext.filter;
173188
}
174189

175190
// connect the input and output streams
176-
if (ctx->videoDemuxer != nullptr)
191+
if (ctx->videoContext.demuxer != nullptr)
177192
{
178-
ctx->videoDemuxer->DecodeBestVideoStream(videoFrameSink);
193+
ctx->videoContext.demuxer->DecodeBestVideoStream(videoFrameSink);
179194
}
180-
if (ctx->audioDemuxer != nullptr)
195+
if (ctx->audioContext.demuxer != nullptr)
181196
{
182-
ctx->audioDemuxer->DecodeBestAudioStream(audioFrameSink);
197+
ctx->audioContext.demuxer->DecodeBestAudioStream(audioFrameSink);
183198
}
184199

185200
// now go over all the streams and process all frames
@@ -207,20 +222,15 @@ void ffmpegCppGenerate(void* handle)
207222
}
208223
}
209224

210-
void ffmpegCppAddFilter(void* handle, const char* filterString)
211-
{
212-
// TODO
213-
}
214-
215-
216225
bool ffmpegCppIsError(void* handle)
217226
{
218227
return ((Context*)handle)->errored;
219228
}
220229

221230
const char* ffmpegCppGetError(void* handle)
222231
{
223-
return ((Context*)handle)->error.c_str();
232+
Context* ctx = (Context*)handle;
233+
return ctx->error;
224234
}
225235

226236
void ffmpegCppClose(void* handle)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// dllmain.cpp : Defines the entry point for the DLL application.
2+
#include <windows.h>
3+
4+
BOOL APIENTRY DllMain(HMODULE hModule,
5+
DWORD ul_reason_for_call,
6+
LPVOID lpReserved
7+
)
8+
{
9+
switch (ul_reason_for_call)
10+
{
11+
case DLL_PROCESS_ATTACH:
12+
case DLL_THREAD_ATTACH:
13+
case DLL_THREAD_DETACH:
14+
case DLL_PROCESS_DETACH:
15+
break;
16+
}
17+
return TRUE;
18+
}
19+

source/ffmpeg-cpp/simple_interface/simple_interface.vcxproj

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
</ProjectConfiguration>
2020
</ItemGroup>
2121
<ItemGroup>
22+
<ClCompile Include="dllmain.cpp" />
2223
<ClCompile Include="SimpleInterface.cpp" />
2324
</ItemGroup>
2425
<ItemGroup>
@@ -51,13 +52,13 @@
5152
<CharacterSet>Unicode</CharacterSet>
5253
</PropertyGroup>
5354
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
54-
<ConfigurationType>StaticLibrary</ConfigurationType>
55+
<ConfigurationType>DynamicLibrary</ConfigurationType>
5556
<UseDebugLibraries>true</UseDebugLibraries>
5657
<PlatformToolset>v141</PlatformToolset>
5758
<CharacterSet>Unicode</CharacterSet>
5859
</PropertyGroup>
5960
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
60-
<ConfigurationType>StaticLibrary</ConfigurationType>
61+
<ConfigurationType>DynamicLibrary</ConfigurationType>
6162
<UseDebugLibraries>false</UseDebugLibraries>
6263
<PlatformToolset>v141</PlatformToolset>
6364
<WholeProgramOptimization>true</WholeProgramOptimization>
@@ -105,7 +106,7 @@
105106
<WarningLevel>Level3</WarningLevel>
106107
<Optimization>Disabled</Optimization>
107108
<SDLCheck>true</SDLCheck>
108-
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
109+
<PreprocessorDefinitions>_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
109110
<ConformanceMode>true</ConformanceMode>
110111
<AdditionalIncludeDirectories>../ffmpeg-cpp;$(FFmpegLibraryDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
111112
</ClCompile>
@@ -154,7 +155,7 @@
154155
<FunctionLevelLinking>true</FunctionLevelLinking>
155156
<IntrinsicFunctions>true</IntrinsicFunctions>
156157
<SDLCheck>true</SDLCheck>
157-
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
158+
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
158159
<ConformanceMode>true</ConformanceMode>
159160
</ClCompile>
160161
<Link>

source/ffmpeg-cpp/simple_interface/simple_interface.vcxproj.filters

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
1515
</Filter>
1616
</ItemGroup>
17-
<ItemGroup>
18-
<ClCompile Include="SimpleInterface.cpp">
19-
<Filter>Resource Files</Filter>
20-
</ClCompile>
21-
</ItemGroup>
2217
<ItemGroup>
2318
<ClInclude Include="SimpleInterface.h">
2419
<Filter>Header Files</Filter>
2520
</ClInclude>
2621
</ItemGroup>
22+
<ItemGroup>
23+
<ClCompile Include="SimpleInterface.cpp">
24+
<Filter>Source Files</Filter>
25+
</ClCompile>
26+
<ClCompile Include="dllmain.cpp">
27+
<Filter>Source Files</Filter>
28+
</ClCompile>
29+
</ItemGroup>
2730
</Project>
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3-
<PropertyGroup />
3+
<PropertyGroup>
4+
<ShowAllFiles>false</ShowAllFiles>
5+
</PropertyGroup>
46
</Project>

0 commit comments

Comments
 (0)