前提
TelloEDUをPythonで操作するため環境構築を行なっています。
https://take6shin-tech-diary.com/tello-video-python3/#toc3
参考:「Tello_VideoをAnaconda Python3環境で動かす」
H.264デコーダをCMakeを使ってビルドする際にエラーが発生しました。
実現したいこと
エラーを消してビルドしたい・・・
発生している問題・エラーメッセージ
$ cmake .. -- Found pybind11: /Users/masudayouko/opt/anaconda3/envs/Tello/include (found version "2.9.2") Using existing pybind11 v2.9.2 -- Configuring done -- Generating done -- Build files have been written to: /Users/masudayouko/h264decoder/build $ cmake --build . Consolidate compiler generated dependencies of target h264decoderlib [ 25%] Building CXX object CMakeFiles/h264decoderlib.dir/src/h264decoder.cpp.o /Users/xxxx/h264decoder/src/h264decoder.cpp:23:3: error: use of undeclared identifier 'avcodec_register_all' avcodec_register_all(); ^ /Users/xxxx/h264decoder/src/h264decoder.cpp:25:11: error: assigning to 'AVCodec *' from 'const AVCodec *' discards qualifiers codec = avcodec_find_decoder(AV_CODEC_ID_H264); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /Users/xxxx/h264decoder/src/h264decoder.cpp:54:3: warning: 'av_init_packet' is deprecated [-Wdeprecated-declarations] av_init_packet(pkt); ^ /usr/local/include/libavcodec/packet.h:505:1: note: 'av_init_packet' has been explicitly marked deprecated here attribute_deprecated ^ /usr/local/include/libavutil/attributes.h:100:49: note: expanded from macro 'attribute_deprecated' # define attribute_deprecated __attribute__((deprecated)) ^ 1 warning and 2 errors generated. make[2]: *** [CMakeFiles/h264decoderlib.dir/src/h264decoder.cpp.o] Error 1 make[1]: *** [CMakeFiles/h264decoderlib.dir/all] Error 2 make: *** [all] Error 2
該当のソースコード
C++
1 2extern "C" { 3#include <libavcodec/avcodec.h> 4#include <libavutil/avutil.h> 5#include <libavutil/imgutils.h> 6#include <libavutil/mem.h> 7#include <libswscale/swscale.h> 8} 9 10#include "h264decoder.hpp" 11#include <utility> // ****** この行を追加 ****** 12 13typedef unsigned char ubyte; 14 15/* For backward compatibility with release 9 or so of libav */ 16#if (LIBAVCODEC_VERSION_MAJOR <= 54) 17# define av_frame_alloc avcodec_alloc_frame 18# define av_frame_free avcodec_free_frame 19#endif 20 21 22H264Decoder::H264Decoder() 23{ 24 avcodec_register_all(); 25 26 codec = avcodec_find_decoder(AV_CODEC_ID_H264); 27 if (!codec) 28 throw H264InitFailure("cannot find decoder"); 29 30 context = avcodec_alloc_context3(codec); 31 if (!context) 32 throw H264InitFailure("cannot allocate context"); 33 34 // Note: CODEC_CAP_TRUNCATED was prefixed with AV_... 35 if(codec->capabilities & AV_CODEC_CAP_TRUNCATED) { 36 context->flags |= AV_CODEC_FLAG_TRUNCATED; 37 } 38 39 int err = avcodec_open2(context, codec, nullptr); 40 if (err < 0) 41 throw H264InitFailure("cannot open context"); 42 43 parser = av_parser_init(AV_CODEC_ID_H264); 44 if (!parser) 45 throw H264InitFailure("cannot init parser"); 46 47 frame = av_frame_alloc(); 48 if (!frame) 49 throw H264InitFailure("cannot allocate frame"); 50 51#if 1 52 pkt = new AVPacket; 53 if (!pkt) 54 throw H264InitFailure("cannot allocate packet"); 55 av_init_packet(pkt); 56#endif 57} 58 59 60H264Decoder::~H264Decoder() 61{ 62 av_parser_close(parser); 63 avcodec_close(context); 64 av_free(context); 65 av_frame_free(&frame); 66#if 1 67 delete pkt; 68#endif 69} 70 71 72ptrdiff_t H264Decoder::parse(const ubyte* in_data, ptrdiff_t in_size) 73{ 74 auto nread = av_parser_parse2(parser, context, &pkt->data, &pkt->size, 75 in_data, in_size, 76 0, 0, AV_NOPTS_VALUE); 77 return nread; 78} 79 80 81bool H264Decoder::is_frame_available() const 82{ 83 return pkt->size > 0; 84} 85 86 87const AVFrame& H264Decoder::decode_frame() 88{ 89#if (LIBAVCODEC_VERSION_MAJOR > 56) 90 int ret; 91 if (pkt) { 92 ret = avcodec_send_packet(context, pkt); 93 if (!ret) { 94 ret = avcodec_receive_frame(context, frame); 95 if (!ret) 96 return *frame; 97 } 98 } 99 throw H264DecodeFailure("error decoding frame"); 100#else 101 int got_picture = 0; 102 int nread = avcodec_decode_video2(context, frame, &got_picture, pkt); 103 if (nread < 0 || got_picture == 0) 104 throw H264DecodeFailure("error decoding frame\n"); 105 return *frame; 106#endif 107} 108 109 110ConverterRGB24::ConverterRGB24() 111{ 112 framergb = av_frame_alloc(); 113 if (!framergb) 114 throw H264DecodeFailure("cannot allocate frame"); 115 context = nullptr; 116} 117 118ConverterRGB24::~ConverterRGB24() 119{ 120 sws_freeContext(context); 121 av_frame_free(&framergb); 122} 123 124 125const AVFrame& ConverterRGB24::convert(const AVFrame &frame, ubyte* out_rgb) 126{ 127 int w = frame.width; 128 int h = frame.height; 129 int pix_fmt = frame.format; 130 131 context = sws_getCachedContext(context, 132 w, h, (AVPixelFormat)pix_fmt, 133 w, h, AV_PIX_FMT_RGB24, SWS_BILINEAR, 134 nullptr, nullptr, nullptr); 135 if (!context) 136 throw H264DecodeFailure("cannot allocate context"); 137 138 // Setup framergb with out_rgb as external buffer. Also say that we want RGB24 output. 139 av_image_fill_arrays(framergb->data, framergb->linesize, out_rgb, AV_PIX_FMT_RGB24, w, h, 1); 140 // Do the conversion. 141 sws_scale(context, frame.data, frame.linesize, 0, h, 142 framergb->data, framergb->linesize); 143 framergb->width = w; 144 framergb->height = h; 145 return *framergb; 146} 147 148/* 149Determine required size of framebuffer. 150 151avpicture_get_size is used in http://dranger.com/ffmpeg/tutorial01.html 152to do this. However, avpicture_get_size returns the size of a compact 153representation, without padding bytes. Since we use av_image_fill_arrays to 154fill the buffer we should also use it to determine the required size. 155*/ 156int ConverterRGB24::predict_size(int w, int h) 157{ 158 return av_image_fill_arrays(framergb->data, framergb->linesize, nullptr, AV_PIX_FMT_RGB24, w, h, 1); 159} 160 161 162 163std::pair<int, int> width_height(const AVFrame& f) 164{ 165 return std::make_pair(f.width, f.height); 166} 167 168int row_size(const AVFrame& f) 169{ 170 return f.linesize[0]; 171} 172 173 174void disable_logging() 175{ 176 av_log_set_level(AV_LOG_QUIET); 177} 178
試したこと
anacondaの再インストール
ffmpegのupdate
ffmpegの再インストール
補足情報(FW/ツールのバージョンなど)
MacOS Monterey 12.2
C++ 13.0.0
Python 3.9.13
conda 4.13.0
ffmpegはHomebrewよりインストールしてあります。
C++は使ったことがないので、初歩的な質問かもしれませんがよろしくお願いします。
回答1件
あなたの回答
tips
プレビュー