FFMpegDecoder.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include "FFMpegDecoder.h"
  11. #define MAX_DELAY_SECOND 60
  12. using namespace std;
  13. using namespace mediakit;
  14. static string ffmpeg_err(int errnum){
  15. char errbuf[AV_ERROR_MAX_STRING_SIZE];
  16. av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
  17. return errbuf;
  18. }
  19. ///////////////////////////////////////////////////////////////////////////
  20. template<bool decoder = true, typename ...ARGS>
  21. AVCodec *getCodecByName(ARGS ...names);
  22. template<bool decoder = true, typename ...ARGS>
  23. AVCodec *getCodecByName(const char *name) {
  24. auto codec = decoder ? avcodec_find_decoder_by_name(name) : avcodec_find_encoder_by_name(name);
  25. if (codec) {
  26. InfoL << (decoder ? "got decoder:" : "got encoder:") << name;
  27. }
  28. return codec;
  29. }
  30. template<bool decoder = true, typename ...ARGS>
  31. AVCodec *getCodecByName(const char *name, ARGS ...names) {
  32. auto codec = getCodecByName<decoder>(names...);
  33. if (codec) {
  34. return codec;
  35. }
  36. return getCodecByName<decoder>(name);
  37. }
  38. template<bool decoder = true>
  39. AVCodec *getCodec(enum AVCodecID id) {
  40. auto codec = decoder ? avcodec_find_decoder(id) : avcodec_find_encoder(id);
  41. if (codec) {
  42. InfoL << (decoder ? "got decoder:" : "got encoder:") << avcodec_get_name(id);
  43. }
  44. return codec;
  45. }
  46. template<bool decoder = true, typename ...ARGS>
  47. AVCodec *getCodec(enum AVCodecID id, ARGS ...names) {
  48. auto codec = getCodecByName<decoder>(names...);
  49. if (codec) {
  50. return codec;
  51. }
  52. return getCodec<decoder>(id);
  53. }
  54. ///////////////////////////////////////////////////////////////////////////
  55. FFmpegFrame::FFmpegFrame(std::shared_ptr<AVFrame> frame) {
  56. if (frame) {
  57. _frame = std::move(frame);
  58. } else {
  59. _frame.reset(av_frame_alloc(), [](AVFrame *ptr) {
  60. av_frame_unref(ptr);
  61. av_frame_free(&ptr);
  62. });
  63. }
  64. }
  65. FFmpegFrame::~FFmpegFrame(){
  66. if (_data) {
  67. delete[] _data;
  68. _data = nullptr;
  69. }
  70. }
  71. AVFrame *FFmpegFrame::get() const{
  72. return _frame.get();
  73. }
  74. ///////////////////////////////////////////////////////////////////////////
  75. FFmpegSwr::FFmpegSwr(AVSampleFormat output, int channel, int channel_layout, int samplerate){
  76. _target_format = output;
  77. _target_channels = channel;
  78. _target_channel_layout = channel_layout;
  79. _target_samplerate = samplerate;
  80. _frame_pool.setSize(8);
  81. }
  82. FFmpegSwr::~FFmpegSwr(){
  83. if (_ctx) {
  84. swr_free(&_ctx);
  85. }
  86. }
  87. FFmpegFrame::Ptr FFmpegSwr::inputFrame(const FFmpegFrame::Ptr &frame){
  88. if (frame->get()->format == _target_format &&
  89. frame->get()->channels == _target_channels &&
  90. frame->get()->channel_layout == _target_channel_layout &&
  91. frame->get()->sample_rate == _target_samplerate) {
  92. //不转格式
  93. return frame;
  94. }
  95. if (!_ctx) {
  96. _ctx = swr_alloc_set_opts(nullptr, _target_channel_layout, _target_format, _target_samplerate,
  97. frame->get()->channel_layout, (AVSampleFormat) frame->get()->format,
  98. frame->get()->sample_rate, 0, nullptr);
  99. InfoL << "swr_alloc_set_opts:" << av_get_sample_fmt_name((enum AVSampleFormat) frame->get()->format) << " -> "
  100. << av_get_sample_fmt_name(_target_format);
  101. }
  102. if (_ctx) {
  103. FFmpegFrame::Ptr out = _frame_pool.obtain();
  104. out->get()->format = _target_format;
  105. out->get()->channel_layout = _target_channel_layout;
  106. out->get()->channels = _target_channels;
  107. out->get()->sample_rate = _target_samplerate;
  108. out->get()->pkt_dts = frame->get()->pkt_dts;
  109. out->get()->pkt_pts = frame->get()->pkt_pts;
  110. out->get()->pts = frame->get()->pts;
  111. int ret;
  112. if(0 != (ret = swr_convert_frame(_ctx, out->get(), frame->get()))){
  113. WarnL << "swr_convert_frame failed:" << ffmpeg_err(ret);
  114. return nullptr;
  115. }
  116. //修正大小
  117. out->get()->linesize[0] = out->get()->nb_samples * out->get()->channels * av_get_bytes_per_sample((enum AVSampleFormat)out->get()->format);
  118. return out;
  119. }
  120. return nullptr;
  121. }
  122. void FFmpegFrame::fillPicture(AVPixelFormat target_format, int target_width, int target_height){
  123. assert(_data == nullptr);
  124. _data = new char[avpicture_get_size(target_format, target_width, target_height)];
  125. avpicture_fill((AVPicture *) _frame.get(), (uint8_t *) _data, target_format, target_width, target_height);
  126. }
  127. ///////////////////////////////////////////////////////////////////////////
  128. FFmpegDecoder::FFmpegDecoder(const Track::Ptr &track) {
  129. _frame_pool.setSize(8);
  130. avcodec_register_all();
  131. AVCodec *codec = nullptr;
  132. AVCodec *codec_default = nullptr;
  133. switch (track->getCodecId()) {
  134. case CodecH264:
  135. codec_default = getCodec(AV_CODEC_ID_H264);
  136. codec = getCodec(AV_CODEC_ID_H264, "h264_cuvid","h264_videotoolbox");
  137. break;
  138. case CodecH265:
  139. codec_default = getCodec(AV_CODEC_ID_HEVC);
  140. codec = getCodec(AV_CODEC_ID_HEVC, "hevc_cuvid","hevc_videotoolbox");
  141. break;
  142. case CodecAAC:
  143. codec = getCodec(AV_CODEC_ID_AAC);
  144. break;
  145. case CodecG711A:
  146. codec = getCodec(AV_CODEC_ID_PCM_ALAW);
  147. break;
  148. case CodecG711U:
  149. codec = getCodec(AV_CODEC_ID_PCM_MULAW);
  150. break;
  151. case CodecOpus:
  152. codec = getCodec(AV_CODEC_ID_OPUS);
  153. break;
  154. default: break;
  155. }
  156. if (!codec) {
  157. throw std::runtime_error("未找到解码器");
  158. }
  159. while (true) {
  160. _context.reset(avcodec_alloc_context3(codec), [](AVCodecContext *ctx) {
  161. avcodec_close(ctx);
  162. avcodec_free_context(&ctx);
  163. });
  164. if (!_context) {
  165. throw std::runtime_error("创建解码器失败");
  166. }
  167. //保存AVFrame的引用
  168. _context->refcounted_frames = 1;
  169. _context->flags |= AV_CODEC_FLAG_LOW_DELAY;
  170. _context->flags2 |= AV_CODEC_FLAG2_FAST;
  171. switch (track->getCodecId()) {
  172. case CodecG711A:
  173. case CodecG711U: {
  174. AudioTrack::Ptr audio = static_pointer_cast<AudioTrack>(track);
  175. _context->channels = audio->getAudioChannel();
  176. _context->sample_rate = audio->getAudioSampleRate();
  177. _context->channel_layout = _context->channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
  178. break;
  179. }
  180. default:
  181. break;
  182. }
  183. AVDictionary *dict = nullptr;
  184. av_dict_set(&dict, "threads", to_string(thread::hardware_concurrency()).data(), 0);
  185. av_dict_set(&dict, "zerolatency", "1", 0);
  186. av_dict_set(&dict, "strict", "-2", 0);
  187. if (codec->capabilities & AV_CODEC_CAP_TRUNCATED) {
  188. /* we do not send complete frames */
  189. _context->flags |= AV_CODEC_FLAG_TRUNCATED;
  190. }
  191. int ret = avcodec_open2(_context.get(), codec, &dict);
  192. if (ret >= 0) {
  193. //成功
  194. InfoL << "打开解码器成功:" << codec->name;
  195. break;
  196. }
  197. if (codec_default && codec_default != codec) {
  198. //硬件编解码器打开失败,尝试软件的
  199. WarnL << "打开解码器" << codec->name << "失败,原因是:" << ffmpeg_err(ret) << ", 再尝试打开解码器" << codec_default->name;
  200. codec = codec_default;
  201. continue;
  202. }
  203. throw std::runtime_error(StrPrinter << "打开解码器" << codec->name << "失败:" << ffmpeg_err(ret));
  204. }
  205. }
  206. void FFmpegDecoder::flush(){
  207. while (true) {
  208. FFmpegFrame::Ptr out_frame = _frame_pool.obtain();
  209. auto ret = avcodec_receive_frame(_context.get(), out_frame->get());
  210. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
  211. break;
  212. }
  213. if (ret < 0) {
  214. WarnL << "avcodec_receive_frame failed:" << ffmpeg_err(ret);
  215. break;
  216. }
  217. onDecode(out_frame);
  218. }
  219. }
  220. const AVCodecContext *FFmpegDecoder::getContext() const{
  221. return _context.get();
  222. }
  223. void FFmpegDecoder::inputFrame(const Frame::Ptr &frame) {
  224. inputFrame(frame->data(), frame->size(), frame->dts(), frame->pts());
  225. }
  226. void FFmpegDecoder::inputFrame(const char *data, size_t size, uint32_t dts, uint32_t pts) {
  227. AVPacket pkt;
  228. av_init_packet(&pkt);
  229. pkt.data = (uint8_t *) data;
  230. pkt.size = size;
  231. pkt.dts = dts;
  232. pkt.pts = pts;
  233. auto ret = avcodec_send_packet(_context.get(), &pkt);
  234. if (ret < 0) {
  235. if (ret != AVERROR_INVALIDDATA) {
  236. WarnL << "avcodec_send_packet failed:" << ffmpeg_err(ret);
  237. }
  238. return;
  239. }
  240. while (true) {
  241. FFmpegFrame::Ptr out_frame = _frame_pool.obtain();
  242. ret = avcodec_receive_frame(_context.get(), out_frame->get());
  243. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
  244. break;
  245. }
  246. if (ret < 0) {
  247. WarnL << "avcodec_receive_frame failed:" << ffmpeg_err(ret);
  248. break;
  249. }
  250. if (pts - out_frame->get()->pkt_pts > MAX_DELAY_SECOND * 1000 && _ticker.createdTime() > 10 * 1000) {
  251. //后面的帧才忽略,防止Track无法ready
  252. WarnL << "解码时,忽略" << MAX_DELAY_SECOND << "秒前的数据:" << pts << " " << out_frame->get()->pkt_pts;
  253. continue;
  254. }
  255. onDecode(out_frame);
  256. }
  257. }
  258. void FFmpegDecoder::setOnDecode(FFmpegDecoder::onDec cb) {
  259. _cb = std::move(cb);
  260. }
  261. void FFmpegDecoder::onDecode(const FFmpegFrame::Ptr &frame){
  262. if (_context->codec_type == AVMEDIA_TYPE_AUDIO) {
  263. if (!_swr) {
  264. //固定输出16位整型的pcm
  265. _swr = std::make_shared<FFmpegSwr>(AV_SAMPLE_FMT_S16, frame->get()->channels, frame->get()->channel_layout, frame->get()->sample_rate);
  266. }
  267. //音频情况下,转换音频format类型,比如说浮点型转换为int型
  268. const_cast<FFmpegFrame::Ptr &>(frame) = _swr->inputFrame(frame);
  269. }
  270. if (_cb && frame) {
  271. _cb(frame);
  272. }
  273. }