media_audio_ffmpeg_loader.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "media/audio/media_audio_ffmpeg_loader.h"
  8. #include "base/bytes.h"
  9. #include "core/file_location.h"
  10. #include "ffmpeg/ffmpeg_utility.h"
  11. #include "media/media_common.h"
  12. extern "C" {
  13. #include <libavfilter/buffersink.h>
  14. #include <libavfilter/buffersrc.h>
  15. } // extern "C"
  16. namespace Media {
  17. namespace {
  18. using FFmpeg::AvErrorWrap;
  19. using FFmpeg::LogError;
  20. } // namespace
  21. #if !DA_FFMPEG_NEW_CHANNEL_LAYOUT
  22. uint64_t AbstractFFMpegLoader::ComputeChannelLayout(
  23. uint64_t channel_layout,
  24. int channels) {
  25. if (channel_layout) {
  26. if (av_get_channel_layout_nb_channels(channel_layout) == channels) {
  27. return channel_layout;
  28. }
  29. }
  30. return av_get_default_channel_layout(channels);
  31. }
  32. #endif // !DA_FFMPEG_NEW_CHANNEL_LAYOUT
  33. int64 AbstractFFMpegLoader::Mul(int64 value, AVRational rational) {
  34. return value * rational.num / rational.den;
  35. }
  36. bool AbstractFFMpegLoader::open(crl::time positionMs, float64 speed) {
  37. if (!AudioPlayerLoader::openFile()) {
  38. return false;
  39. }
  40. ioBuffer = (uchar *)av_malloc(FFmpeg::kAVBlockSize);
  41. if (!_data.isEmpty()) {
  42. ioContext = avio_alloc_context(ioBuffer, FFmpeg::kAVBlockSize, 0, reinterpret_cast<void *>(this), &AbstractFFMpegLoader::ReadData, 0, &AbstractFFMpegLoader::SeekData);
  43. } else if (!_bytes.empty()) {
  44. ioContext = avio_alloc_context(ioBuffer, FFmpeg::kAVBlockSize, 0, reinterpret_cast<void *>(this), &AbstractFFMpegLoader::ReadBytes, 0, &AbstractFFMpegLoader::SeekBytes);
  45. } else {
  46. ioContext = avio_alloc_context(ioBuffer, FFmpeg::kAVBlockSize, 0, reinterpret_cast<void *>(this), &AbstractFFMpegLoader::ReadFile, 0, &AbstractFFMpegLoader::SeekFile);
  47. }
  48. fmtContext = avformat_alloc_context();
  49. if (!fmtContext) {
  50. LogError(u"avformat_alloc_context"_q);
  51. return false;
  52. }
  53. fmtContext->pb = ioContext;
  54. if (AvErrorWrap error = avformat_open_input(&fmtContext, 0, 0, 0)) {
  55. ioBuffer = nullptr;
  56. LogError(u"avformat_open_input"_q, error);
  57. return false;
  58. }
  59. _opened = true;
  60. if (AvErrorWrap error = avformat_find_stream_info(fmtContext, 0)) {
  61. LogError(u"avformat_find_stream_info"_q, error);
  62. return false;
  63. }
  64. streamId = av_find_best_stream(fmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
  65. if (streamId < 0) {
  66. FFmpeg::LogError(u"av_find_best_stream"_q, AvErrorWrap(streamId));
  67. return false;
  68. }
  69. const auto stream = fmtContext->streams[streamId];
  70. const auto params = stream->codecpar;
  71. _samplesFrequency = params->sample_rate;
  72. if (stream->duration != AV_NOPTS_VALUE) {
  73. _duration = Mul(stream->duration * 1000, stream->time_base);
  74. } else {
  75. _duration = Mul(fmtContext->duration * 1000, { 1, AV_TIME_BASE });
  76. }
  77. _startedAtSample = (positionMs * _samplesFrequency) / 1000LL;
  78. return true;
  79. }
  80. AbstractFFMpegLoader::~AbstractFFMpegLoader() {
  81. if (_opened) {
  82. avformat_close_input(&fmtContext);
  83. }
  84. if (ioContext) {
  85. av_freep(&ioContext->buffer);
  86. av_freep(&ioContext);
  87. } else if (ioBuffer) {
  88. av_freep(&ioBuffer);
  89. }
  90. if (fmtContext) avformat_free_context(fmtContext);
  91. }
  92. int AbstractFFMpegLoader::ReadData(void *opaque, uint8_t *buf, int buf_size) {
  93. auto l = reinterpret_cast<AbstractFFMpegLoader *>(opaque);
  94. auto nbytes = qMin(l->_data.size() - l->_dataPos, int32(buf_size));
  95. if (nbytes <= 0) {
  96. return AVERROR_EOF;
  97. }
  98. memcpy(buf, l->_data.constData() + l->_dataPos, nbytes);
  99. l->_dataPos += nbytes;
  100. return nbytes;
  101. }
  102. int64_t AbstractFFMpegLoader::SeekData(void *opaque, int64_t offset, int whence) {
  103. auto l = reinterpret_cast<AbstractFFMpegLoader *>(opaque);
  104. int32 newPos = -1;
  105. switch (whence) {
  106. case SEEK_SET: newPos = offset; break;
  107. case SEEK_CUR: newPos = l->_dataPos + offset; break;
  108. case SEEK_END: newPos = l->_data.size() + offset; break;
  109. case AVSEEK_SIZE: {
  110. // Special whence for determining filesize without any seek.
  111. return l->_data.size();
  112. } break;
  113. }
  114. if (newPos < 0 || newPos > l->_data.size()) {
  115. return -1;
  116. }
  117. l->_dataPos = newPos;
  118. return l->_dataPos;
  119. }
  120. int AbstractFFMpegLoader::ReadBytes(void *opaque, uint8_t *buf, int buf_size) {
  121. auto l = reinterpret_cast<AbstractFFMpegLoader *>(opaque);
  122. auto nbytes = qMin(static_cast<int>(l->_bytes.size()) - l->_dataPos, buf_size);
  123. if (nbytes <= 0) {
  124. return AVERROR_EOF;
  125. }
  126. memcpy(buf, l->_bytes.data() + l->_dataPos, nbytes);
  127. l->_dataPos += nbytes;
  128. return nbytes;
  129. }
  130. int64_t AbstractFFMpegLoader::SeekBytes(void *opaque, int64_t offset, int whence) {
  131. auto l = reinterpret_cast<AbstractFFMpegLoader *>(opaque);
  132. int32 newPos = -1;
  133. switch (whence) {
  134. case SEEK_SET: newPos = offset; break;
  135. case SEEK_CUR: newPos = l->_dataPos + offset; break;
  136. case SEEK_END: newPos = static_cast<int>(l->_bytes.size()) + offset; break;
  137. case AVSEEK_SIZE:
  138. {
  139. // Special whence for determining filesize without any seek.
  140. return l->_bytes.size();
  141. } break;
  142. }
  143. if (newPos < 0 || newPos > l->_bytes.size()) {
  144. return -1;
  145. }
  146. l->_dataPos = newPos;
  147. return l->_dataPos;
  148. }
  149. int AbstractFFMpegLoader::ReadFile(void *opaque, uint8_t *buf, int buf_size) {
  150. auto l = reinterpret_cast<AbstractFFMpegLoader *>(opaque);
  151. int ret = l->_f.read((char *)(buf), buf_size);
  152. switch (ret) {
  153. case -1: return AVERROR_EXTERNAL;
  154. case 0: return AVERROR_EOF;
  155. default: return ret;
  156. }
  157. }
  158. int64_t AbstractFFMpegLoader::SeekFile(void *opaque, int64_t offset, int whence) {
  159. auto l = reinterpret_cast<AbstractFFMpegLoader *>(opaque);
  160. switch (whence) {
  161. case SEEK_SET: return l->_f.seek(offset) ? l->_f.pos() : -1;
  162. case SEEK_CUR: return l->_f.seek(l->_f.pos() + offset) ? l->_f.pos() : -1;
  163. case SEEK_END: return l->_f.seek(l->_f.size() + offset) ? l->_f.pos() : -1;
  164. case AVSEEK_SIZE:
  165. {
  166. // Special whence for determining filesize without any seek.
  167. return l->_f.size();
  168. } break;
  169. }
  170. return -1;
  171. }
  172. AbstractAudioFFMpegLoader::AbstractAudioFFMpegLoader(
  173. const Core::FileLocation &file,
  174. const QByteArray &data,
  175. bytes::vector &&buffer)
  176. : AbstractFFMpegLoader(file, data, std::move(buffer))
  177. , _frame(FFmpeg::MakeFramePointer()) {
  178. }
  179. void AbstractAudioFFMpegLoader::dropFramesTill(int64 samples) {
  180. const auto isAfter = [&](const EnqueuedFrame &frame) {
  181. return frame.position > samples;
  182. };
  183. const auto from = begin(_framesQueued);
  184. const auto after = ranges::find_if(_framesQueued, isAfter);
  185. if (from == after) {
  186. return;
  187. }
  188. const auto till = after - 1;
  189. const auto erasing = till - from;
  190. if (erasing > 0) {
  191. if (_framesQueuedIndex >= 0) {
  192. Assert(_framesQueuedIndex >= erasing);
  193. _framesQueuedIndex -= erasing;
  194. }
  195. _framesQueued.erase(from, till);
  196. if (_framesQueued.empty()) {
  197. _framesQueuedIndex = -1;
  198. }
  199. }
  200. }
  201. int64 AbstractAudioFFMpegLoader::startReadingQueuedFrames(float64 newSpeed) {
  202. changeSpeedFilter(newSpeed);
  203. if (_framesQueued.empty()) {
  204. _framesQueuedIndex = -1;
  205. return -1;
  206. }
  207. _framesQueuedIndex = 0;
  208. return _framesQueued.front().position;
  209. }
  210. bool AbstractAudioFFMpegLoader::initUsingContext(
  211. not_null<AVCodecContext*> context,
  212. float64 speed) {
  213. _swrSrcSampleFormat = context->sample_fmt;
  214. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  215. const AVChannelLayout mono = AV_CHANNEL_LAYOUT_MONO;
  216. const AVChannelLayout stereo = AV_CHANNEL_LAYOUT_STEREO;
  217. const auto useMono = !av_channel_layout_compare(
  218. &context->ch_layout,
  219. &mono);
  220. const auto useStereo = !av_channel_layout_compare(
  221. &context->ch_layout,
  222. &stereo);
  223. const auto copyDstChannelLayout = [&] {
  224. av_channel_layout_copy(&_swrDstChannelLayout, &context->ch_layout);
  225. };
  226. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  227. const auto layout = ComputeChannelLayout(
  228. context->channel_layout,
  229. context->channels);
  230. if (!layout) {
  231. LOG(("Audio Error: Unknown channel layout %1 for %2 channels."
  232. ).arg(context->channel_layout
  233. ).arg(context->channels
  234. ));
  235. return false;
  236. }
  237. const auto useMono = (layout == AV_CH_LAYOUT_MONO);
  238. const auto useStereo = (layout == AV_CH_LAYOUT_STEREO);
  239. const auto copyDstChannelLayout = [&] {
  240. _swrDstChannelLayout = layout;
  241. };
  242. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  243. if (useMono) {
  244. switch (_swrSrcSampleFormat) {
  245. case AV_SAMPLE_FMT_U8:
  246. case AV_SAMPLE_FMT_U8P:
  247. _swrDstSampleFormat = _swrSrcSampleFormat;
  248. copyDstChannelLayout();
  249. _outputChannels = 1;
  250. _outputSampleSize = 1;
  251. _outputFormat = AL_FORMAT_MONO8;
  252. break;
  253. case AV_SAMPLE_FMT_S16:
  254. case AV_SAMPLE_FMT_S16P:
  255. _swrDstSampleFormat = _swrSrcSampleFormat;
  256. copyDstChannelLayout();
  257. _outputChannels = 1;
  258. _outputSampleSize = sizeof(uint16);
  259. _outputFormat = AL_FORMAT_MONO16;
  260. break;
  261. }
  262. } else if (useStereo) {
  263. switch (_swrSrcSampleFormat) {
  264. case AV_SAMPLE_FMT_U8:
  265. _swrDstSampleFormat = _swrSrcSampleFormat;
  266. copyDstChannelLayout();
  267. _outputChannels = 2;
  268. _outputSampleSize = 2;
  269. _outputFormat = AL_FORMAT_STEREO8;
  270. break;
  271. case AV_SAMPLE_FMT_S16:
  272. _swrDstSampleFormat = _swrSrcSampleFormat;
  273. copyDstChannelLayout();
  274. _outputChannels = 2;
  275. _outputSampleSize = 2 * sizeof(uint16);
  276. _outputFormat = AL_FORMAT_STEREO16;
  277. break;
  278. }
  279. }
  280. createSpeedFilter(speed);
  281. return true;
  282. }
  283. auto AbstractAudioFFMpegLoader::replaceFrameAndRead(
  284. FFmpeg::FramePointer frame)
  285. -> ReadResult {
  286. _frame = std::move(frame);
  287. return readFromReadyFrame();
  288. }
  289. auto AbstractAudioFFMpegLoader::readFromReadyContext(
  290. not_null<AVCodecContext*> context)
  291. -> ReadResult {
  292. if (_filterGraph) {
  293. AvErrorWrap error = av_buffersink_get_frame(
  294. _filterSink,
  295. _filteredFrame.get());
  296. if (!error) {
  297. if (!_filteredFrame->nb_samples) {
  298. return ReadError::Retry;
  299. }
  300. return bytes::const_span(
  301. reinterpret_cast<const bytes::type*>(
  302. _filteredFrame->extended_data[0]),
  303. _filteredFrame->nb_samples * _outputSampleSize);
  304. } else if (error.code() == AVERROR_EOF) {
  305. return ReadError::EndOfFile;
  306. } else if (error.code() != AVERROR(EAGAIN)) {
  307. LogError(u"av_buffersink_get_frame"_q, error);
  308. return ReadError::Other;
  309. }
  310. }
  311. using Enqueued = not_null<const EnqueuedFrame*>;
  312. const auto queueResult = fillFrameFromQueued();
  313. if (queueResult == ReadError::RetryNotQueued) {
  314. return ReadError::RetryNotQueued;
  315. } else if (const auto enqueued = std::get_if<Enqueued>(&queueResult)) {
  316. const auto raw = (*enqueued)->frame.get();
  317. Assert(frameHasDesiredFormat(raw));
  318. return readOrBufferForFilter(raw, (*enqueued)->samples);
  319. }
  320. const auto queueError = v::get<ReadError>(queueResult);
  321. AvErrorWrap error = (queueError == ReadError::EndOfFile)
  322. ? AVERROR_EOF
  323. : avcodec_receive_frame(context, _frame.get());
  324. if (!error) {
  325. return readFromReadyFrame();
  326. }
  327. if (error.code() == AVERROR_EOF) {
  328. enqueueFramesFinished();
  329. if (!_filterGraph) {
  330. return ReadError::EndOfFile;
  331. }
  332. AvErrorWrap error = av_buffersrc_add_frame(_filterSrc, nullptr);
  333. if (!error) {
  334. return ReadError::Retry;
  335. }
  336. LogError(u"av_buffersrc_add_frame"_q, error);
  337. return ReadError::Other;
  338. } else if (error.code() != AVERROR(EAGAIN)) {
  339. LogError(u"avcodec_receive_frame"_q, error);
  340. return ReadError::Other;
  341. }
  342. return ReadError::Wait;
  343. }
  344. auto AbstractAudioFFMpegLoader::fillFrameFromQueued()
  345. -> std::variant<not_null<const EnqueuedFrame*>, ReadError> {
  346. if (_framesQueuedIndex == _framesQueued.size()) {
  347. _framesQueuedIndex = -1;
  348. return ReadError::RetryNotQueued;
  349. } else if (_framesQueuedIndex < 0) {
  350. return ReadError::Wait;
  351. }
  352. const auto &queued = _framesQueued[_framesQueuedIndex];
  353. ++_framesQueuedIndex;
  354. if (!queued.frame) {
  355. return ReadError::EndOfFile;
  356. }
  357. return &queued;
  358. }
  359. bool AbstractAudioFFMpegLoader::frameHasDesiredFormat(
  360. not_null<AVFrame*> frame) const {
  361. const auto sameChannelLayout = [&] {
  362. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  363. return !av_channel_layout_compare(
  364. &frame->ch_layout,
  365. &_swrDstChannelLayout);
  366. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  367. const auto frameChannelLayout = ComputeChannelLayout(
  368. frame->channel_layout,
  369. frame->channels);
  370. return (frameChannelLayout == _swrDstChannelLayout);
  371. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  372. };
  373. return true
  374. && (frame->format == _swrDstSampleFormat)
  375. && (frame->sample_rate == _swrDstRate)
  376. && sameChannelLayout();
  377. }
  378. bool AbstractAudioFFMpegLoader::initResampleForFrame() {
  379. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  380. const auto bad = !_frame->ch_layout.nb_channels;
  381. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  382. const auto frameChannelLayout = ComputeChannelLayout(
  383. _frame->channel_layout,
  384. _frame->channels);
  385. const auto bad = !frameChannelLayout;
  386. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  387. if (bad) {
  388. LOG(("Audio Error: "
  389. "Unknown channel layout for frame in file '%1', "
  390. "data size '%2'"
  391. ).arg(_file.name()
  392. ).arg(_data.size()
  393. ));
  394. return false;
  395. } else if (_frame->format == -1) {
  396. LOG(("Audio Error: "
  397. "Unknown frame format in file '%1', data size '%2'"
  398. ).arg(_file.name()
  399. ).arg(_data.size()
  400. ));
  401. return false;
  402. } else if (_swrContext) {
  403. const auto sameChannelLayout = [&] {
  404. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  405. return !av_channel_layout_compare(
  406. &_frame->ch_layout,
  407. &_swrSrcChannelLayout);
  408. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  409. return (frameChannelLayout == _swrSrcChannelLayout);
  410. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  411. };
  412. if (true
  413. && (_frame->format == _swrSrcSampleFormat)
  414. && (_frame->sample_rate == _swrSrcRate)
  415. && sameChannelLayout()) {
  416. return true;
  417. }
  418. swr_close(_swrContext);
  419. }
  420. _swrSrcSampleFormat = static_cast<AVSampleFormat>(_frame->format);
  421. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  422. av_channel_layout_copy(&_swrSrcChannelLayout, &_frame->ch_layout);
  423. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  424. _swrSrcChannelLayout = frameChannelLayout;
  425. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  426. _swrSrcRate = _frame->sample_rate;
  427. return initResampleUsingFormat();
  428. }
  429. bool AbstractAudioFFMpegLoader::initResampleUsingFormat() {
  430. AvErrorWrap error = 0;
  431. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  432. error = swr_alloc_set_opts2(
  433. &_swrContext,
  434. &_swrDstChannelLayout,
  435. _swrDstSampleFormat,
  436. _swrDstRate,
  437. &_swrSrcChannelLayout,
  438. _swrSrcSampleFormat,
  439. _swrSrcRate,
  440. 0,
  441. nullptr);
  442. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  443. _swrContext = swr_alloc_set_opts(
  444. _swrContext,
  445. _swrDstChannelLayout,
  446. _swrDstSampleFormat,
  447. _swrDstRate,
  448. _swrSrcChannelLayout,
  449. _swrSrcSampleFormat,
  450. _swrSrcRate,
  451. 0,
  452. nullptr);
  453. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  454. if (error || !_swrContext) {
  455. LogError(u"swr_alloc_set_opts2"_q, error);
  456. return false;
  457. } else if (AvErrorWrap error = swr_init(_swrContext)) {
  458. LogError(u"swr_init"_q, error);
  459. return false;
  460. }
  461. _resampledFrame = nullptr;
  462. _resampledFrameCapacity = 0;
  463. return true;
  464. }
  465. bool AbstractAudioFFMpegLoader::ensureResampleSpaceAvailable(int samples) {
  466. const auto enlarge = (_resampledFrameCapacity < samples);
  467. if (!_resampledFrame) {
  468. _resampledFrame = FFmpeg::MakeFramePointer();
  469. } else if (enlarge || !av_frame_is_writable(_resampledFrame.get())) {
  470. av_frame_unref(_resampledFrame.get());
  471. } else {
  472. return true;
  473. }
  474. const auto allocate = std::max(samples, int(av_rescale_rnd(
  475. FFmpeg::kAVBlockSize / _outputSampleSize,
  476. _swrDstRate,
  477. _swrSrcRate,
  478. AV_ROUND_UP)));
  479. _resampledFrame->sample_rate = _swrDstRate;
  480. _resampledFrame->format = _swrDstSampleFormat;
  481. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  482. av_channel_layout_copy(
  483. &_resampledFrame->ch_layout,
  484. &_swrDstChannelLayout);
  485. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  486. _resampledFrame->channel_layout = _swrDstChannelLayout;
  487. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  488. _resampledFrame->nb_samples = allocate;
  489. if (AvErrorWrap error = av_frame_get_buffer(_resampledFrame.get(), 0)) {
  490. LogError(u"av_frame_get_buffer"_q, error);
  491. return false;
  492. }
  493. _resampledFrameCapacity = allocate;
  494. return true;
  495. }
  496. bool AbstractAudioFFMpegLoader::changeSpeedFilter(float64 speed) {
  497. speed = std::clamp(speed, kSpeedMin, kSpeedMax);
  498. if (EqualSpeeds(_filterSpeed, speed)) {
  499. return false;
  500. }
  501. avfilter_graph_free(&_filterGraph);
  502. const auto guard = gsl::finally([&] {
  503. if (!_filterGraph) {
  504. _filteredFrame = nullptr;
  505. _filterSpeed = 1.;
  506. }
  507. });
  508. createSpeedFilter(speed);
  509. return true;
  510. }
  511. void AbstractAudioFFMpegLoader::createSpeedFilter(float64 speed) {
  512. Expects(!_filterGraph);
  513. if (EqualSpeeds(speed, 1.)) {
  514. return;
  515. }
  516. const auto abuffer = avfilter_get_by_name("abuffer");
  517. const auto abuffersink = avfilter_get_by_name("abuffersink");
  518. const auto atempo = avfilter_get_by_name("atempo");
  519. if (!abuffer || !abuffersink || !atempo) {
  520. LOG(("FFmpeg Error: Could not find abuffer / abuffersink /atempo."));
  521. return;
  522. }
  523. auto graph = avfilter_graph_alloc();
  524. if (!graph) {
  525. LOG(("FFmpeg Error: Unable to create filter graph."));
  526. return;
  527. }
  528. const auto guard = gsl::finally([&] {
  529. avfilter_graph_free(&graph);
  530. });
  531. _filterSrc = avfilter_graph_alloc_filter(graph, abuffer, "src");
  532. _atempo = avfilter_graph_alloc_filter(graph, atempo, "atempo");
  533. _filterSink = avfilter_graph_alloc_filter(graph, abuffersink, "sink");
  534. if (!_filterSrc || !atempo || !_filterSink) {
  535. LOG(("FFmpeg Error: "
  536. "Could not allocate abuffer / abuffersink /atempo."));
  537. return;
  538. }
  539. char layout[64] = { 0 };
  540. #if DA_FFMPEG_NEW_CHANNEL_LAYOUT
  541. av_channel_layout_describe(
  542. &_swrDstChannelLayout,
  543. layout,
  544. sizeof(layout));
  545. #else // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  546. av_get_channel_layout_string(
  547. layout,
  548. sizeof(layout),
  549. 0,
  550. _swrDstChannelLayout);
  551. #endif // DA_FFMPEG_NEW_CHANNEL_LAYOUT
  552. av_opt_set(
  553. _filterSrc,
  554. "channel_layout",
  555. layout,
  556. AV_OPT_SEARCH_CHILDREN);
  557. av_opt_set_sample_fmt(
  558. _filterSrc,
  559. "sample_fmt",
  560. _swrDstSampleFormat,
  561. AV_OPT_SEARCH_CHILDREN);
  562. av_opt_set_q(
  563. _filterSrc,
  564. "time_base",
  565. AVRational{ 1, _swrDstRate },
  566. AV_OPT_SEARCH_CHILDREN);
  567. av_opt_set_int(
  568. _filterSrc,
  569. "sample_rate",
  570. _swrDstRate,
  571. AV_OPT_SEARCH_CHILDREN);
  572. av_opt_set_double(
  573. _atempo,
  574. "tempo",
  575. speed,
  576. AV_OPT_SEARCH_CHILDREN);
  577. AvErrorWrap error = 0;
  578. if ((error = avfilter_init_str(_filterSrc, nullptr))) {
  579. LogError(u"avfilter_init_str(src)"_q, error);
  580. return;
  581. } else if ((error = avfilter_init_str(_atempo, nullptr))) {
  582. LogError(u"avfilter_init_str(atempo)"_q, error);
  583. avfilter_graph_free(&graph);
  584. return;
  585. } else if ((error = avfilter_init_str(_filterSink, nullptr))) {
  586. LogError(u"avfilter_init_str(sink)"_q, error);
  587. avfilter_graph_free(&graph);
  588. return;
  589. } else if ((error = avfilter_link(_filterSrc, 0, _atempo, 0))) {
  590. LogError(u"avfilter_link(src->atempo)"_q, error);
  591. avfilter_graph_free(&graph);
  592. return;
  593. } else if ((error = avfilter_link(_atempo, 0, _filterSink, 0))) {
  594. LogError(u"avfilter_link(atempo->sink)"_q, error);
  595. avfilter_graph_free(&graph);
  596. return;
  597. } else if ((error = avfilter_graph_config(graph, nullptr))) {
  598. LogError("avfilter_link(atempo->sink)"_q, error);
  599. avfilter_graph_free(&graph);
  600. return;
  601. }
  602. _filterGraph = base::take(graph);
  603. _filteredFrame = FFmpeg::MakeFramePointer();
  604. _filterSpeed = speed;
  605. }
  606. void AbstractAudioFFMpegLoader::enqueueNormalFrame(
  607. not_null<AVFrame*> frame,
  608. int64 samples) {
  609. if (_framesQueuedIndex >= 0) {
  610. return;
  611. }
  612. if (!samples) {
  613. samples = frame->nb_samples;
  614. }
  615. _framesQueued.push_back({
  616. .position = startedAtSample() + _framesQueuedSamples,
  617. .samples = samples,
  618. .frame = FFmpeg::DuplicateFramePointer(frame),
  619. });
  620. _framesQueuedSamples += samples;
  621. }
  622. void AbstractAudioFFMpegLoader::enqueueFramesFinished() {
  623. if (_framesQueuedIndex >= 0) {
  624. return;
  625. }
  626. _framesQueued.push_back({
  627. .position = startedAtSample() + _framesQueuedSamples,
  628. });
  629. }
  630. auto AbstractAudioFFMpegLoader::readFromReadyFrame()
  631. -> ReadResult {
  632. const auto raw = _frame.get();
  633. if (frameHasDesiredFormat(raw)) {
  634. if (!raw->nb_samples) {
  635. return ReadError::Retry;
  636. }
  637. return readOrBufferForFilter(raw, raw->nb_samples);
  638. } else if (!initResampleForFrame()) {
  639. return ReadError::Other;
  640. }
  641. const auto maxSamples = av_rescale_rnd(
  642. swr_get_delay(_swrContext, _swrSrcRate) + _frame->nb_samples,
  643. _swrDstRate,
  644. _swrSrcRate,
  645. AV_ROUND_UP);
  646. if (!ensureResampleSpaceAvailable(maxSamples)) {
  647. return ReadError::Other;
  648. }
  649. const auto samples = swr_convert(
  650. _swrContext,
  651. (uint8_t**)_resampledFrame->extended_data,
  652. maxSamples,
  653. (const uint8_t **)_frame->extended_data,
  654. _frame->nb_samples);
  655. if (AvErrorWrap error = samples) {
  656. LogError(u"swr_convert"_q, error);
  657. return ReadError::Other;
  658. } else if (!samples) {
  659. return ReadError::Retry;
  660. }
  661. return readOrBufferForFilter(_resampledFrame.get(), samples);
  662. }
  663. auto AbstractAudioFFMpegLoader::readOrBufferForFilter(
  664. not_null<AVFrame*> frame,
  665. int64 samplesOverride)
  666. -> ReadResult {
  667. enqueueNormalFrame(frame, samplesOverride);
  668. const auto was = frame->nb_samples;
  669. frame->nb_samples = samplesOverride;
  670. const auto guard = gsl::finally([&] {
  671. frame->nb_samples = was;
  672. });
  673. if (!_filterGraph) {
  674. return bytes::const_span(
  675. reinterpret_cast<const bytes::type*>(frame->extended_data[0]),
  676. frame->nb_samples * _outputSampleSize);
  677. }
  678. AvErrorWrap error = av_buffersrc_add_frame_flags(
  679. _filterSrc,
  680. frame,
  681. AV_BUFFERSRC_FLAG_KEEP_REF);
  682. if (error) {
  683. LogError(u"av_buffersrc_add_frame_flags"_q, error);
  684. return ReadError::Other;
  685. }
  686. return ReadError::Retry;
  687. }
  688. AbstractAudioFFMpegLoader::~AbstractAudioFFMpegLoader() {
  689. if (_filterGraph) {
  690. avfilter_graph_free(&_filterGraph);
  691. }
  692. if (_swrContext) {
  693. swr_free(&_swrContext);
  694. }
  695. }
  696. FFMpegLoader::FFMpegLoader(
  697. const Core::FileLocation &file,
  698. const QByteArray &data,
  699. bytes::vector &&buffer)
  700. : AbstractAudioFFMpegLoader(file, data, std::move(buffer)) {
  701. }
  702. bool FFMpegLoader::open(crl::time positionMs, float64 speed) {
  703. return AbstractFFMpegLoader::open(positionMs)
  704. && openCodecContext()
  705. && initUsingContext(_codecContext, speed)
  706. && seekTo(positionMs);
  707. }
  708. bool FFMpegLoader::openCodecContext() {
  709. _codecContext = avcodec_alloc_context3(nullptr);
  710. if (!_codecContext) {
  711. LOG(("Audio Error: "
  712. "Unable to avcodec_alloc_context3 for file '%1', data size '%2'"
  713. ).arg(_file.name()
  714. ).arg(_data.size()
  715. ));
  716. return false;
  717. }
  718. const auto stream = fmtContext->streams[streamId];
  719. AvErrorWrap error = avcodec_parameters_to_context(
  720. _codecContext,
  721. stream->codecpar);
  722. if (error) {
  723. LogError(u"avcodec_parameters_to_context"_q, error);
  724. return false;
  725. }
  726. _codecContext->pkt_timebase = stream->time_base;
  727. av_opt_set_int(_codecContext, "refcounted_frames", 1, 0);
  728. if (AvErrorWrap error = avcodec_open2(_codecContext, codec, 0)) {
  729. LogError(u"avcodec_open2"_q, error);
  730. return false;
  731. }
  732. return true;
  733. }
  734. bool FFMpegLoader::seekTo(crl::time positionMs) {
  735. if (positionMs) {
  736. const auto stream = fmtContext->streams[streamId];
  737. const auto timeBase = stream->time_base;
  738. const auto timeStamp = (positionMs * timeBase.den)
  739. / (1000LL * timeBase.num);
  740. const auto flags1 = AVSEEK_FLAG_ANY;
  741. if (av_seek_frame(fmtContext, streamId, timeStamp, flags1) < 0) {
  742. const auto flags2 = 0;
  743. if (av_seek_frame(fmtContext, streamId, timeStamp, flags2) < 0) {
  744. }
  745. }
  746. }
  747. return true;
  748. }
  749. FFMpegLoader::ReadResult FFMpegLoader::readMore() {
  750. if (_readTillEnd) {
  751. return ReadError::EndOfFile;
  752. }
  753. const auto readResult = readFromReadyContext(_codecContext);
  754. if (readResult != ReadError::Wait) {
  755. if (readResult == ReadError::EndOfFile) {
  756. _readTillEnd = true;
  757. }
  758. return readResult;
  759. }
  760. if (AvErrorWrap error = av_read_frame(fmtContext, &_packet)) {
  761. if (error.code() != AVERROR_EOF) {
  762. LogError(u"av_read_frame"_q, error);
  763. return ReadError::Other;
  764. }
  765. error = avcodec_send_packet(_codecContext, nullptr); // drain
  766. if (!error) {
  767. return ReadError::Retry;
  768. }
  769. LogError(u"avcodec_send_packet"_q, error);
  770. return ReadError::Other;
  771. }
  772. if (_packet.stream_index == streamId) {
  773. AvErrorWrap error = avcodec_send_packet(_codecContext, &_packet);
  774. if (error) {
  775. av_packet_unref(&_packet);
  776. LogError(u"avcodec_send_packet"_q, error);
  777. // There is a sample voice message where skipping such packet
  778. // results in a crash (read_access to nullptr) in swr_convert().
  779. //if (error.code() == AVERROR_INVALIDDATA) {
  780. // return ReadResult::Retry; // try to skip bad packet
  781. //}
  782. return ReadError::Other;
  783. }
  784. }
  785. av_packet_unref(&_packet);
  786. return ReadError::Retry;
  787. }
  788. FFMpegLoader::~FFMpegLoader() {
  789. if (_codecContext) {
  790. avcodec_free_context(&_codecContext);
  791. }
  792. }
  793. } // namespace Media