@@ -50,6 +50,7 @@ void Decoder::reset()
5050 outputFrame_ = NULL ;
5151 hwPixFormat_ = AV_PIX_FMT_NONE;
5252 outputMsgEncoding_ = " " ;
53+ packetEncoding_ = " " ;
5354}
5455
5556void Decoder::setOutputMessageEncoding (const std::string & output_encoding)
@@ -58,61 +59,29 @@ void Decoder::setOutputMessageEncoding(const std::string & output_encoding)
5859 outputMsgEncoding_ = output_encoding;
5960}
6061
61- bool Decoder::initialize (
62- const std::string & encoding, Callback callback, const std::string & decoder)
62+ static std::vector<std::string> splitEncoding (const std::string & encoding)
6363{
64- return (initialize (
65- encoding, callback,
66- decoder.empty () ? std::vector<std::string>() : std::vector<std::string>{decoder}));
64+ return (utils::split_by_char (encoding, ' ;' ));
6765}
6866
69- bool Decoder::initialize (
70- const std::string & encoding, Callback callback, const std::vector<std::string> & decoders)
67+ void Decoder::setEncoding (const std::string & encoding)
7168{
72- callback_ = callback;
7369 packetEncoding_ = encoding;
74- const auto split = utils::split_by_char (encoding, ' / ' );
70+ const auto split = splitEncoding (encoding);
7571 if (outputMsgEncoding_.empty ()) {
7672 // assume orig was bgr8
77- outputMsgEncoding_ = split.size () > 1 ? split[1 ] : " bgr8" ;
73+ outputMsgEncoding_ = split.size () == 4 ? split[3 ] : " bgr8" ;
7874 RCLCPP_INFO_STREAM (
7975 logger_,
80- " output image encoding: " << outputMsgEncoding_ << ((split.size () > 1 ) ? " " : " (default)" ));
81- }
82- const auto all_decoders = findDecoders (split[0 ]);
83- if (all_decoders.empty ()) {
84- RCLCPP_ERROR_STREAM (logger_, " no decoders discovered for code:c " << split[0 ]);
85- throw (std::runtime_error (" no decoders discovered for codec: " + split[0 ]));
86- }
87- if (decoders.empty ()) { // try all libav-discovered decoders
88- std::string decoders_str;
89- for (const auto & decoder : all_decoders) {
90- decoders_str += " " + decoder;
91- }
92- RCLCPP_INFO_STREAM (logger_, " trying discovered decoders in order:" << decoders_str);
93- return (initDecoder (all_decoders));
94- }
95- const auto good_decoders = filterDecoders (encoding, decoders, all_decoders);
96- if (good_decoders.empty ()) {
97- return (false );
76+ " output image encoding: " << outputMsgEncoding_ << ((split.size () == 4 ) ? " " : " (default)" ));
9877 }
99- return (initDecoder (good_decoders));
10078}
10179
102- std::vector<std::string> Decoder::filterDecoders (
103- const std::string & encoding, const std::vector<std::string> & decoders,
104- const std::vector<std::string> & valid_decoders)
80+ bool Decoder::initialize (
81+ const std::string & encoding, Callback callback, const std::string & decoder)
10582{
106- std::vector<std::string> good_decoders;
107- for (const auto & dec : decoders) { // filter for decoders matching codec
108- if (std::find (valid_decoders.begin (), valid_decoders.end (), dec) != valid_decoders.end ()) {
109- good_decoders.push_back (dec);
110- } else {
111- RCLCPP_WARN_STREAM (
112- logger_, " configured decoder: " << dec << " cannot handle encoding: " << encoding);
113- }
114- }
115- return (good_decoders);
83+ callback_ = callback;
84+ return (initDecoder (encoding, decoder));
11685}
11786
11887static AVBufferRef * hw_decoder_init (
@@ -232,46 +201,32 @@ enum AVPixelFormat get_format(struct AVCodecContext * avctx, const enum AVPixelF
232201 return AV_PIX_FMT_NONE;
233202}
234203
235- bool Decoder::initDecoder (const std::vector< std::string> & decoders )
204+ bool Decoder::initDecoder (const std::string & encoding, const std::string & decoder )
236205{
237- if (decoders.empty ()) {
238- RCLCPP_ERROR_STREAM (logger_, " no decoders configured for this encoding!" );
239- throw (std::runtime_error (" no decoders configured for this encoding!" ));
206+ const AVCodec * codec = avcodec_find_decoder_by_name (decoder.c_str ());
207+ if (!codec) {
208+ RCLCPP_WARN_STREAM (logger_, " decoder " << decoder << " cannot decode " << encoding);
209+ return (false );
240210 }
241- for (const auto & decoder : decoders) {
242- const AVCodec * codec = avcodec_find_decoder_by_name (decoder.c_str ());
243- if (codec) {
244- // use the decoder if it either is software, or has working
245- // hardware support
246- if (codec->capabilities & AV_CODEC_CAP_HARDWARE) {
247- const AVCodecHWConfig * hwConfig = avcodec_get_hw_config (codec, 0 );
248- if (hwConfig) {
249- if (initSingleDecoder (decoder)) {
250- return (true );
251- }
252- } else {
253- RCLCPP_INFO_STREAM (logger_, " ignoring decoder with no hardware config: " << decoder);
254- }
255- } else {
256- if (initSingleDecoder (decoder)) {
257- return (true );
258- }
259- }
260- } else {
261- RCLCPP_WARN_STREAM (logger_, " unknown decoder: " << decoder);
211+ // use the decoder if it either is software, or has working
212+ // hardware support
213+ const AVCodecHWConfig * hwConfig = nullptr ;
214+ if (codec->capabilities & AV_CODEC_CAP_HARDWARE) {
215+ hwConfig = avcodec_get_hw_config (codec, 0 );
216+ if (!hwConfig) {
217+ RCLCPP_INFO_STREAM (logger_, " ignoring decoder with no hardware config: " << decoder);
218+ return (false );
262219 }
263220 }
264- if (decoders.size () > 1 ) {
265- RCLCPP_ERROR_STREAM (logger_, " none of these requested decoders works: " );
266- for (const auto & decoder : decoders) {
267- RCLCPP_ERROR_STREAM (logger_, " " << decoder);
268- }
221+ if (!doInitDecoder (encoding, decoder)) {
222+ return (false );
269223 }
270- throw ( std::runtime_error ( " cannot find matching decoder! " ) );
224+ return ( true );
271225}
272226
273- bool Decoder::initSingleDecoder ( const std::string & decoder)
227+ bool Decoder::doInitDecoder ( const std::string & encoding, const std::string & decoder)
274228{
229+ setEncoding (encoding);
275230 try {
276231 const AVCodec * codec = avcodec_find_decoder_by_name (decoder.c_str ());
277232 if (!codec) {
@@ -373,7 +328,6 @@ int Decoder::receiveFrame()
373328 }
374329 }
375330 AVFrame * frame = isAcc ? cpuFrame_ : swFrame_;
376-
377331 if (frame->width == ctx->width && frame->height == ctx->height ) {
378332 // prepare the decoded message
379333 ImagePtr image (new Image ());
@@ -504,26 +458,28 @@ void Decoder::setAVOption(const std::string & field, const std::string & value)
504458 }
505459}
506460
507- const std::unordered_map<std::string, std::string> & Decoder::getDefaultEncoderToDecoderMap ()
508- {
509- RCLCPP_INFO_STREAM (
510- rclcpp::get_logger (" ffmpeg_decoder" ),
511- " default map is deprecated, use findDecoders() or pass empty string instead!" );
512- throw (std::runtime_error (" default map is deprecated!" ));
513- }
514-
515461void Decoder::findDecoders (
516462 const std::string & codec, std::vector<std::string> * hw_decoders,
517463 std::vector<std::string> * sw_decoders)
518464{
519465 utils::find_decoders (codec, hw_decoders, sw_decoders);
520466}
521467
522- std::vector<std:: string> Decoder::findDecoders (const std::string & codec)
468+ std::string Decoder::findDecoders (const std::string & codec)
523469{
524- std::vector<std::string> sw_decoders, all_decoders;
525- utils::find_decoders (codec, &all_decoders, &sw_decoders);
526- all_decoders.insert (all_decoders.end (), sw_decoders.begin (), sw_decoders.end ());
527- return (all_decoders);
470+ return (utils::find_decoders (codec));
528471}
472+
473+ // -------------- deprecated, DO NOT USE ------------------
474+ const std::unordered_map<std::string, std::string> & Decoder::getDefaultEncoderToDecoderMap ()
475+ {
476+ static const std::unordered_map<std::string, std::string> defaultMap{
477+ {{" h264_nvenc" , " h264" },
478+ {" libx264" , " h264" },
479+ {" hevc_nvenc" , " hevc_cuvid" },
480+ {" h264_nvmpi" , " h264" },
481+ {" h264_vaapi" , " h264" }}};
482+ return (defaultMap);
483+ }
484+
529485} // namespace ffmpeg_encoder_decoder
0 commit comments