Skip to content

Commit 8eee769

Browse files
MarcAntoine-Arnaudvalnoel
authored andcommitted
add API to use an external encoder
1 parent b49c7c0 commit 8eee769

File tree

11 files changed

+436
-3
lines changed

11 files changed

+436
-3
lines changed

app/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_subdirectory(avInfo)
33
add_subdirectory(avMeta)
44
add_subdirectory(avPlayer)
55
add_subdirectory(avProcessor)
6+
add_subdirectory(customEncoder)
67

78
# Python apps
89
add_subdirectory(pyProcessor)

app/customEncoder/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
### cpp/customEncoder
2+
3+
# Load custom cmake utilities
4+
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
5+
include(AvTranscoderMacros)
6+
7+
# Build app
8+
add_executable(custom-encoder customEncoder.cpp)
9+
set_target_properties(custom-encoder PROPERTIES VERSION ${AVTRANSCODER_VERSION})
10+
target_link_libraries(custom-encoder avtranscoder-shared)
11+
12+
# Install app
13+
if(WIN32)
14+
set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder.exe")
15+
else()
16+
set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder" "${CMAKE_CURRENT_BINARY_DIR}/custom-encoder-${AVTRANSCODER_VERSION}")
17+
endif()
18+
19+
install(
20+
FILES ${BINARY_FILES}
21+
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE
22+
DESTINATION "bin/"
23+
OPTIONAL
24+
)

app/customEncoder/customEncoder.cpp

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#include <AvTranscoder/transcoder/Transcoder.hpp>
2+
#include <AvTranscoder/file/OutputFile.hpp>
3+
#include <AvTranscoder/progress/ConsoleProgress.hpp>
4+
5+
#include <iostream>
6+
#include <iomanip>
7+
#include <vector>
8+
#include <fstream>
9+
#include <sstream>
10+
#include <cstdlib>
11+
12+
void parseConfigFile(const std::string& configFilename, avtranscoder::Transcoder& transcoder)
13+
{
14+
std::ifstream configFile(configFilename.c_str(), std::ifstream::in);
15+
16+
std::string line;
17+
while(std::getline(configFile, line))
18+
{
19+
std::istringstream is_line(line);
20+
std::string filename;
21+
if(std::getline(is_line, filename, '='))
22+
{
23+
std::string streamId;
24+
if(std::getline(is_line, streamId, ':'))
25+
{
26+
std::string transcodeProfile;
27+
std::getline(is_line, transcodeProfile);
28+
29+
std::stringstream ss(streamId);
30+
size_t streamIndex = 0;
31+
char separator = 'x';
32+
std::vector<size_t> channelIndexArray;
33+
ss >> streamIndex;
34+
ss >> separator;
35+
if(separator == '.')
36+
{
37+
int subStreamIndex = -1;
38+
ss >> subStreamIndex;
39+
channelIndexArray.push_back(subStreamIndex);
40+
}
41+
42+
// generated stream
43+
if(!filename.length())
44+
transcoder.addGenerateStream(transcodeProfile);
45+
else
46+
{
47+
avtranscoder::InputStreamDesc inputDesc(filename, streamIndex, channelIndexArray);
48+
transcoder.addStream(inputDesc, transcodeProfile);
49+
}
50+
}
51+
}
52+
}
53+
54+
configFile.close();
55+
}
56+
57+
58+
59+
class AvExport CustomCodec
60+
: public avtranscoder::ICodec
61+
{
62+
public:
63+
CustomCodec()
64+
: avtranscoder::ICodec(avtranscoder::eCodecTypeEncoder, AV_CODEC_ID_PCM_S24LE)
65+
{
66+
}
67+
68+
void openCodec(){}
69+
void closeCodec(){}
70+
71+
std::string getCodecName() const { return "Custom Encoder"; };
72+
AVCodecID getCodecId() const { return AV_CODEC_ID_PCM_S24LE; }
73+
avtranscoder::ECodecType getCodecType() const { return avtranscoder::eCodecTypeEncoder; }
74+
int getLatency() const { return 0; }
75+
76+
avtranscoder::OptionArray getOptions() {
77+
std::vector<avtranscoder::Option> options;
78+
return options;
79+
}
80+
};
81+
82+
83+
class AvExport CustomEncoder
84+
: public avtranscoder::IEncoder
85+
{
86+
public:
87+
CustomEncoder()
88+
: _codec(CustomCodec())
89+
{}
90+
/**
91+
* @brief Setup the encoder
92+
* @param profile: set encoder parameters from the given profile
93+
* @note Open the encoder.
94+
*/
95+
void setupEncoder(const avtranscoder::ProfileLoader::Profile& profile = avtranscoder::ProfileLoader::Profile()) {
96+
return;
97+
};
98+
99+
/**
100+
* @brief Encode a new frame, and get coded frame
101+
* @param sourceFrame: frame that needs to be encoded
102+
* @param codedFrame: output encoded coded data (first frames can be delayed)
103+
* @return status of encoding
104+
* @throw runtime_error if the encoded process failed.
105+
*/
106+
bool encodeFrame(const avtranscoder::IFrame& sourceFrame, avtranscoder::CodedData& codedFrame) {
107+
codedFrame.assign(5760, 0);
108+
return true;
109+
};
110+
111+
/**
112+
* @brief Get the frames remaining into the encoder
113+
* @param codedFrame: output encoded data
114+
* @return status of encoding
115+
* @throw runtime_error if the encoded process failed.
116+
*/
117+
bool encodeFrame(avtranscoder::CodedData& codedFrame) {
118+
return false;
119+
};
120+
121+
/**
122+
* @brief Get codec used for encoding.
123+
* @return a reference to the codec
124+
*/
125+
avtranscoder::ICodec& getCodec() {
126+
return _codec;
127+
};
128+
129+
private:
130+
CustomCodec _codec;
131+
};
132+
133+
134+
int main(int argc, char** argv)
135+
{
136+
std::string help;
137+
help += "Usage\n";
138+
help += "\tavprocessor INPUT_FILE_NAME OUTPUT_FILE_NAME [--verbose] [--logFile] [--help]\n";
139+
help += "Command line options\n";
140+
help += "\t--verbose: set log level to AV_LOG_DEBUG\n";
141+
help += "\t--logFile: put log in 'avtranscoder.log' file\n";
142+
help += "\t--help: display this help\n";
143+
144+
// Preload FFmpeg context
145+
avtranscoder::preloadCodecsAndFormats();
146+
avtranscoder::Logger::setLogLevel(AV_LOG_QUIET);
147+
148+
// List command line arguments
149+
std::vector<std::string> arguments;
150+
for(int argument = 1; argument < argc; ++argument)
151+
{
152+
arguments.push_back(argv[argument]);
153+
}
154+
for(size_t argument = 0; argument < arguments.size(); ++argument)
155+
{
156+
if(arguments.at(argument) == "--help")
157+
{
158+
std::cout << help << std::endl;
159+
return 0;
160+
}
161+
else if(arguments.at(argument) == "--verbose")
162+
{
163+
avtranscoder::Logger::setLogLevel(AV_LOG_DEBUG);
164+
}
165+
else if(arguments.at(argument) == "--logFile")
166+
{
167+
avtranscoder::Logger::logInFile();
168+
}
169+
}
170+
171+
// Check required arguments
172+
if(argc < 3)
173+
{
174+
std::cout << "avprocessor can rewrap or transcode inputs to create an output media file." << std::endl;
175+
std::cout << "Use option --help to display help" << std::endl;
176+
return (-1);
177+
}
178+
179+
try
180+
{
181+
std::string output_format = "s24le";
182+
avtranscoder::OutputFile outputFile(argv[2], output_format);
183+
184+
avtranscoder::Transcoder transcoder(outputFile);
185+
transcoder.setProcessMethod(avtranscoder::eProcessMethodBasedOnStream);
186+
187+
CustomEncoder* customEncoder = new CustomEncoder;
188+
avtranscoder::InputStreamDesc inputDescLeft(argv[1], 1, 0);
189+
avtranscoder::InputStreamDesc inputDescRight(argv[1], 2, 0);
190+
191+
std::vector<avtranscoder::InputStreamDesc> inputDescriptors;
192+
inputDescriptors.push_back(avtranscoder::InputStreamDesc(argv[1], 1, 0));
193+
inputDescriptors.push_back(avtranscoder::InputStreamDesc(argv[1], 2, 0));
194+
195+
transcoder.addStream(inputDescriptors, customEncoder);
196+
197+
avtranscoder::ConsoleProgress progress;
198+
transcoder.process(progress);
199+
}
200+
catch(std::exception& e)
201+
{
202+
std::cerr << "ERROR: during process, an error occured: " << e.what() << std::endl;
203+
}
204+
catch(...)
205+
{
206+
std::cerr << "ERROR: during process, an unknown error occured" << std::endl;
207+
}
208+
}

src/AvTranscoder/codec/ICodec.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ enum ECodecType
2525
class AvExport ICodec
2626
{
2727
private:
28-
ICodec(const ICodec& iCodec);
2928
ICodec& operator=(const ICodec& iCodec);
3029

3130
public:
31+
ICodec(const ICodec& iCodec);
3232
ICodec(const ECodecType type, const std::string& codecName);
3333
ICodec(const ECodecType type, const AVCodecID codecId);
3434
ICodec(const ECodecType type, AVCodecContext& avCodecContext);

src/AvTranscoder/file/IOutputFile.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,15 @@ class AvExport IOutputFile
5151
throw std::logic_error("function is not implemented");
5252
}
5353

54+
/**
55+
* @brief Add a custom output stream
56+
* @param iCodecDesc description of output codec
57+
**/
58+
virtual IOutputStream& addCustomStream(const ICodec& iCodecDesc)
59+
{
60+
throw std::logic_error("function is not implemented");
61+
}
62+
5463
/**
5564
* @brief Write the header of file (if necessary)
5665
**/

src/AvTranscoder/file/OutputFile.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,25 @@ IOutputStream& OutputFile::addAudioStream(const AudioCodec& audioDesc)
8888
return *outputStream;
8989
}
9090

91+
IOutputStream& OutputFile::addCustomStream(const ICodec& iCodecDesc)
92+
{
93+
AVStream& stream = _formatContext.addAVStream(iCodecDesc.getAVCodec());
94+
95+
stream.codec->sample_rate = 48000;
96+
stream.codec->channels = 1;
97+
stream.codec->channel_layout = AV_CH_LAYOUT_MONO;
98+
stream.codec->sample_fmt = AV_SAMPLE_FMT_S32;
99+
stream.codec->frame_size = 1920;
100+
101+
// need to set the time_base on the AVCodecContext of the AVStream
102+
av_reduce(&stream.codec->time_base.num, &stream.codec->time_base.den, 1, 1, INT_MAX);
103+
104+
OutputStream* outputStream = new OutputStream(*this, _formatContext.getNbStreams() - 1);
105+
_outputStreams.push_back(outputStream);
106+
107+
return *outputStream;
108+
}
109+
91110
IOutputStream& OutputFile::addDataStream(const DataCodec& dataDesc)
92111
{
93112
_formatContext.addAVStream(dataDesc.getAVCodec());

src/AvTranscoder/file/OutputFile.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class AvExport OutputFile : public IOutputFile
3737
IOutputStream& addVideoStream(const VideoCodec& videoDesc);
3838
IOutputStream& addAudioStream(const AudioCodec& audioDesc);
3939
IOutputStream& addDataStream(const DataCodec& dataDesc);
40+
IOutputStream& addCustomStream(const ICodec& iCodecDesc);
4041

4142
/**
4243
* @brief Open ressource, write header, and setup specific wrapping options given when call setupWrapping.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy