PageRenderTime 60ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/src/av/streamcoder.cpp

https://gitlab.com/live-transcoder/transcoder
C++ | 802 lines | 627 code | 151 blank | 24 comment | 131 complexity | 6deb439a01793fef71661551fa586938 MD5 | raw file
  1. #include <cassert>
  2. #include "audiosamples.h"
  3. #include "streamcoder.h"
  4. #include "avutils.h"
  5. namespace av
  6. {
  7. StreamCoder::StreamCoder()
  8. {
  9. init();
  10. }
  11. StreamCoder::~StreamCoder()
  12. {
  13. close();
  14. }
  15. StreamCoder::StreamCoder(const StreamPtr &stream)
  16. {
  17. init();
  18. this->stream = stream;
  19. context = stream->getAVStream()->codec;
  20. CodecPtr codec;
  21. if (stream->getDirection() == DECODING)
  22. {
  23. codec = Codec::findDecodingCodec(context->codec_id);
  24. }
  25. else
  26. {
  27. codec = Codec::findEncodingCodec(context->codec_id);
  28. }
  29. if (codec)
  30. setCodec(codec);
  31. direction = stream->getDirection();
  32. setTimeBase(context->time_base);
  33. }
  34. void StreamCoder::setCodec(const CodecPtr &codec)
  35. {
  36. if (!codec)
  37. {
  38. cout << "Cannot set codec to null codec\n";
  39. return;
  40. }
  41. AVCodec *avCodec = codec->getAVCodec();
  42. if (!context)
  43. {
  44. cout << "Codec context does not allocated\n";
  45. return;
  46. }
  47. if (context->codec_id != CODEC_ID_NONE && context->codec)
  48. {
  49. cout << "Codec already set to: " << context->codec_id << " / " << context->codec_name << ", ignoring." << endl;
  50. return;
  51. }
  52. if (this->codec == codec)
  53. {
  54. cout << "Try set same codec\n";
  55. return;
  56. }
  57. context->codec_id = avCodec ? avCodec->id : CODEC_ID_NONE;
  58. context->codec_type = avCodec ? avCodec->type : AVMEDIA_TYPE_UNKNOWN;
  59. context->codec = avCodec;
  60. if (avCodec->pix_fmts != 0)
  61. {
  62. context->pix_fmt = *(avCodec->pix_fmts); // assign default value
  63. }
  64. if (avCodec->sample_fmts != 0)
  65. {
  66. context->sample_fmt = *(avCodec->sample_fmts);
  67. }
  68. // else
  69. // {
  70. // context->pix_fmt = PIX_FMT_NONE;
  71. // }
  72. this->codec = codec;
  73. }
  74. void StreamCoder::init()
  75. {
  76. isOpenedFlag = false;
  77. fakePtsTimeBase = Rational(1, AV_TIME_BASE);
  78. context = 0;
  79. fakeCurrPts = AV_NOPTS_VALUE;
  80. fakeNextPts = AV_NOPTS_VALUE;
  81. defaultAudioFrameSize = 576;
  82. }
  83. ssize_t StreamCoder::decodeCommon(const FramePtr &outFrame, const PacketPtr &inPacket, size_t offset, int (*decodeProc)(AVCodecContext *, AVFrame *, int *, const AVPacket *))
  84. {
  85. assert(context);
  86. boost::shared_ptr<AVFrame> frame(avcodec_alloc_frame(), AvDeleter());
  87. if (!frame)
  88. {
  89. return -1;
  90. }
  91. if (!decodeProc)
  92. {
  93. return -1;
  94. }
  95. if (offset >= inPacket->getSize())
  96. {
  97. return -1;
  98. }
  99. outFrame->setComplete(false);
  100. int frameFinished = 0;
  101. boost::shared_ptr<AVPacket> pkt((AVPacket*)av_malloc(sizeof(AVPacket)), AvDeleter());
  102. av_init_packet(pkt.get());
  103. *pkt = *inPacket->getAVPacket();
  104. pkt->data = const_cast<uint8_t*>(inPacket->getData());
  105. pkt->size = inPacket->getSize();
  106. pkt->destruct = 0; // prevent data free
  107. pkt->data += offset;
  108. pkt->size -= offset;
  109. context->reordered_opaque = inPacket->getPts();
  110. ssize_t totalDecode = 0;
  111. int iterations = 0;
  112. do
  113. {
  114. ++iterations;
  115. int decoded = decodeProc(context, frame.get(), &frameFinished, pkt.get());
  116. if (decoded < 0)
  117. {
  118. return totalDecode;
  119. }
  120. totalDecode += decoded;
  121. pkt->data += decoded;
  122. pkt->size -= decoded;
  123. }
  124. while (frameFinished == 0 && pkt->size > 0);
  125. if (frameFinished)
  126. {
  127. *outFrame.get() = frame.get();
  128. outFrame->setTimeBase(getTimeBase());
  129. int64_t packetTs = frame->reordered_opaque;
  130. if (packetTs == AV_NOPTS_VALUE)
  131. {
  132. packetTs = inPacket->getDts();
  133. }
  134. if (packetTs != AV_NOPTS_VALUE)
  135. {
  136. //int64_t nextPts = fakePtsTimeBase.rescale(packetTs, outFrame->getTimeBase());
  137. int64_t nextPts = packetTs;
  138. if (nextPts < fakeNextPts && inPacket->getPts() != AV_NOPTS_VALUE)
  139. {
  140. nextPts = inPacket->getPts();
  141. }
  142. fakeNextPts = nextPts;
  143. }
  144. fakeCurrPts = fakeNextPts;
  145. //double frameDelay = inPacket->getTimeBase().getNumerator();
  146. double frameDelay = inPacket->getTimeBase().getDouble();
  147. frameDelay += outFrame->getAVFrame()->repeat_pict * (frameDelay * 0.5);
  148. fakeNextPts += (int64_t) frameDelay;
  149. outFrame->setStreamIndex(inPacket->getStreamIndex());
  150. if (fakeCurrPts != AV_NOPTS_VALUE)
  151. outFrame->setPts(inPacket->getTimeBase().rescale(fakeCurrPts, outFrame->getTimeBase()));
  152. outFrame->setComplete(true);
  153. }
  154. return totalDecode;
  155. }
  156. ssize_t StreamCoder::encodeCommon(const PacketPtr &outPacket, const FramePtr &inFrame,
  157. int (*encodeProc)(AVCodecContext *, AVPacket *, const AVFrame *, int *),
  158. const EncodedPacketHandler &onPacketHandler)
  159. {
  160. if (!outPacket && !onPacketHandler.empty())
  161. {
  162. cerr << "Null packet can't be used as target for encoded data\n";
  163. return -1;
  164. }
  165. if (!inFrame)
  166. {
  167. cerr << "Null frame can't be encoded\n";
  168. return -1;
  169. }
  170. if (!isValidForEncode())
  171. {
  172. return -1;
  173. }
  174. if (!encodeProc)
  175. {
  176. return -1;
  177. }
  178. // Be thread-safe, make our own copy of encoded frame
  179. FramePtr frame = inFrame->clone();
  180. // Change frame's pts and time base to coder's based values
  181. frame->setTimeBase(getTimeBase());
  182. if (context->codec_type == AVMEDIA_TYPE_AUDIO)
  183. {
  184. PacketPtr workPacket = outPacket;
  185. if (!workPacket)
  186. {
  187. workPacket = PacketPtr(new Packet());
  188. }
  189. // set timebase to coder timebase
  190. workPacket->setTimeBase(getTimeBase());
  191. AudioSamplesPtr samples = boost::dynamic_pointer_cast<AudioSamples>(frame);
  192. int gotPacket;
  193. int stat = encodeProc(context, workPacket->getAVPacket(), samples->getAVFrame(), &gotPacket);
  194. if (stat == 0)
  195. {
  196. if (gotPacket)
  197. {
  198. // Change timebase to target stream timebase, it also recalculate all TS values
  199. // (pts, dts, duration)
  200. workPacket->setTimeBase(stream->getTimeBase());
  201. workPacket->setStreamIndex(samples->getStreamIndex());
  202. if (samples->getFakePts() != AV_NOPTS_VALUE)
  203. {
  204. workPacket->setFakePts(samples->getTimeBase()
  205. .rescale(samples->getFakePts(),
  206. workPacket->getTimeBase()));
  207. }
  208. if (!onPacketHandler.empty())
  209. {
  210. onPacketHandler(workPacket);
  211. }
  212. }
  213. }
  214. else
  215. {
  216. cout << "Encode error: " << stat << endl;
  217. cout << "coded_frame PTS: " << context->coded_frame->pts << endl;
  218. cout << "input_frame PTS: " << inFrame->getPts() << endl;
  219. return stat;
  220. }
  221. }
  222. else if (context->codec_type == AVMEDIA_TYPE_VIDEO)
  223. {
  224. PacketPtr workPacket = outPacket;
  225. if (!workPacket)
  226. {
  227. workPacket = PacketPtr(new Packet());
  228. }
  229. int gotPacket;
  230. int stat = encodeProc(context, workPacket->getAVPacket(), frame->getAVFrame(), &gotPacket);
  231. if (stat == 0)
  232. {
  233. if (gotPacket)
  234. {
  235. // Packet always must be in AVStream time base units
  236. workPacket->setTimeBase(stream->getTimeBase());
  237. if (context->coded_frame->pts != AV_NOPTS_VALUE)
  238. {
  239. workPacket->setPts(getTimeBase().rescale(context->coded_frame->pts,
  240. workPacket->getTimeBase()));
  241. }
  242. if (workPacket->getDts() == AV_NOPTS_VALUE && workPacket->getPts() != AV_NOPTS_VALUE)
  243. {
  244. workPacket->setDts(workPacket->getPts());
  245. }
  246. else
  247. {
  248. workPacket->setDts(getTimeBase().rescale(workPacket->getDts(),
  249. workPacket->getTimeBase()));
  250. }
  251. workPacket->setKeyPacket(!!context->coded_frame->key_frame);
  252. workPacket->setStreamIndex(frame->getStreamIndex());
  253. if (!onPacketHandler.empty())
  254. {
  255. onPacketHandler(workPacket);
  256. }
  257. }
  258. }
  259. else
  260. {
  261. cout << "Encode error: " << stat << endl;
  262. cout << "coded_frame PTS: " << context->coded_frame->pts << endl;
  263. cout << "input_frame PTS: " << inFrame->getPts() << endl;
  264. return stat;
  265. }
  266. }
  267. return 0;
  268. }
  269. bool StreamCoder::open()
  270. {
  271. if (context && codec)
  272. {
  273. // HACK: set threads to 1
  274. AVDictionary *opts = 0;
  275. av_dict_set(&opts, "threads", "1", 0);
  276. ////////////////////////////////////////////////////////////////////////////////////////////
  277. bool ret = true;
  278. int stat = avcodec_open2(context, codec->getAVCodec(), &opts);
  279. if (stat < 0)
  280. {
  281. ret = false;
  282. }
  283. else
  284. {
  285. isOpenedFlag = true;
  286. }
  287. av_dict_free(&opts);
  288. return ret;
  289. }
  290. return false;
  291. }
  292. bool StreamCoder::close()
  293. {
  294. if (context && codec && isOpenedFlag)
  295. {
  296. avcodec_close(context);
  297. isOpenedFlag = false;
  298. return true;
  299. }
  300. return false;
  301. }
  302. Rational StreamCoder::getTimeBase()
  303. {
  304. return (context ? context->time_base : Rational());
  305. }
  306. void StreamCoder::setTimeBase(const Rational &value)
  307. {
  308. if (context)
  309. {
  310. context->time_base = value.getValue();
  311. }
  312. }
  313. StreamPtr StreamCoder::getStream() const
  314. {
  315. return stream;
  316. }
  317. AVMediaType StreamCoder::getCodecType() const
  318. {
  319. return (context ? context->codec_type : AVMEDIA_TYPE_UNKNOWN);
  320. }
  321. int StreamCoder::getWidth() const
  322. {
  323. return (context ? context->width : -1);
  324. }
  325. int StreamCoder::getHeight() const
  326. {
  327. return (context ? context->height : -1);
  328. }
  329. PixelFormat StreamCoder::getPixelFormat() const
  330. {
  331. return (context ? context->pix_fmt : PIX_FMT_NONE);
  332. }
  333. Rational StreamCoder::getFrameRate()
  334. {
  335. if (!isOpenedFlag && stream)
  336. {
  337. return stream->getFrameRate();
  338. }
  339. return Rational();
  340. }
  341. int32_t StreamCoder::getBitRate() const
  342. {
  343. return (context ? context->bit_rate : 0);
  344. }
  345. pair<int,int> StreamCoder::getBitRateRange() const
  346. {
  347. return (context ? std::pair<int,int>(context->rc_min_rate, context->rc_max_rate) : std::pair<int,int>());
  348. }
  349. int32_t StreamCoder::getGlobalQuality()
  350. {
  351. return (context ? context->global_quality : FF_LAMBDA_MAX);
  352. }
  353. int32_t StreamCoder::getGopSize()
  354. {
  355. return (context ? context->gop_size : -1);
  356. }
  357. int StreamCoder::getBitRateTolerance() const
  358. {
  359. return (context ? context->bit_rate_tolerance : -1);
  360. }
  361. int StreamCoder::getStrict() const
  362. {
  363. return (context ? context->strict_std_compliance : 0);
  364. }
  365. int StreamCoder::getMaxBFrames() const
  366. {
  367. return (context ? context->max_b_frames : 0);
  368. }
  369. int StreamCoder::getFrameSize() const
  370. {
  371. assert(context);
  372. return context->frame_size;
  373. }
  374. void StreamCoder::setWidth(int w)
  375. {
  376. if (context)
  377. {
  378. context->width = w;
  379. }
  380. }
  381. void StreamCoder::setHeight(int h)
  382. {
  383. if (context)
  384. context->height = h;
  385. }
  386. void StreamCoder::setPixelFormat(PixelFormat pixelFormat)
  387. {
  388. if (context)
  389. context->pix_fmt = pixelFormat;
  390. }
  391. void StreamCoder::setFrameRate(const Rational &frameRate)
  392. {
  393. if (!isOpenedFlag && stream)
  394. stream->setFrameRate(frameRate);
  395. }
  396. void StreamCoder::setBitRate(int32_t bitRate)
  397. {
  398. if (context && !isOpenedFlag)
  399. context->bit_rate = bitRate;
  400. }
  401. void StreamCoder::setBitRateRange(const std::pair<int, int> &bitRateRange)
  402. {
  403. if (context && !isOpenedFlag)
  404. {
  405. context->rc_min_rate = bitRateRange.first;
  406. context->rc_max_rate = bitRateRange.second;
  407. }
  408. }
  409. void StreamCoder::setGlobalQuality(int32_t quality)
  410. {
  411. if (quality < 0 || quality > FF_LAMBDA_MAX)
  412. quality = FF_LAMBDA_MAX;
  413. if (context)
  414. context->global_quality = quality;
  415. }
  416. void StreamCoder::setGopSize(int32_t size)
  417. {
  418. if (context)
  419. context->gop_size = size;
  420. }
  421. void StreamCoder::setBitRateTolerance(int bitRateTolerance)
  422. {
  423. if (context)
  424. context->bit_rate_tolerance = bitRateTolerance;
  425. }
  426. void StreamCoder::setStrict(int strict)
  427. {
  428. if (context)
  429. {
  430. if (strict < FF_COMPLIANCE_EXPERIMENTAL)
  431. {
  432. strict = FF_COMPLIANCE_EXPERIMENTAL;
  433. }
  434. else if (strict > FF_COMPLIANCE_VERY_STRICT)
  435. {
  436. strict = FF_COMPLIANCE_VERY_STRICT;
  437. }
  438. context->strict_std_compliance = strict;
  439. }
  440. }
  441. void StreamCoder::setMaxBFrames(int maxBFrames)
  442. {
  443. if (context)
  444. context->max_b_frames = maxBFrames;
  445. }
  446. int StreamCoder::getSampleRate() const
  447. {
  448. return (context ? context->sample_rate : -1);
  449. }
  450. int StreamCoder::getChannels() const
  451. {
  452. if (!context)
  453. {
  454. return 0;
  455. }
  456. if (context->channels)
  457. {
  458. return context->channels;
  459. }
  460. if (context->channel_layout)
  461. {
  462. return av_get_channel_layout_nb_channels(context->channel_layout);
  463. }
  464. return 0;
  465. }
  466. AVSampleFormat StreamCoder::getSampleFormat() const
  467. {
  468. return (context ? context->sample_fmt : AV_SAMPLE_FMT_NONE);
  469. }
  470. uint64_t StreamCoder::getChannelLayout() const
  471. {
  472. if (!context)
  473. {
  474. return 0;
  475. }
  476. if (context->channel_layout)
  477. {
  478. return context->channel_layout;
  479. }
  480. if (context->channels)
  481. {
  482. return av_get_default_channel_layout(context->channels);
  483. }
  484. return 0;
  485. }
  486. int StreamCoder::getAudioFrameSize() const
  487. {
  488. int result = 0;
  489. if (codec && codec->getAVCodec()->type == AVMEDIA_TYPE_AUDIO)
  490. {
  491. if (context)
  492. {
  493. if (context->frame_size <= 1)
  494. {
  495. // Rats; some PCM encoders give a frame size of 1, which is too
  496. //small. We pick a more sensible value.
  497. result = defaultAudioFrameSize;
  498. }
  499. else
  500. {
  501. result = context->frame_size;
  502. }
  503. }
  504. }
  505. return result;
  506. }
  507. int StreamCoder::getDefaultAudioFrameSize() const
  508. {
  509. return defaultAudioFrameSize;
  510. }
  511. void StreamCoder::setSampleRate(int sampleRate)
  512. {
  513. assert(context);
  514. if (!isOpenedFlag)
  515. {
  516. int sr = guessValue(sampleRate, context->codec->supported_samplerates, EqualComparator<int>(0));
  517. clog << "========= Input sampleRate: " << sampleRate << ", guessed sample rate: " << sr << endl;
  518. if (sr > 0)
  519. context->sample_rate = sr;
  520. }
  521. }
  522. void StreamCoder::setChannels(int channels)
  523. {
  524. if (context && !isOpenedFlag && channels > 0)
  525. {
  526. context->channels = channels;
  527. // Make channels and channel_layout sync
  528. if (context->channel_layout == 0 ||
  529. av_get_channel_layout_nb_channels(context->channel_layout) != channels)
  530. {
  531. context->channel_layout = av_get_default_channel_layout(channels);
  532. }
  533. }
  534. }
  535. void StreamCoder::setSampleFormat(AVSampleFormat sampleFormat)
  536. {
  537. if (context && !isOpenedFlag && sampleFormat >= 0)
  538. {
  539. context->sample_fmt = sampleFormat;
  540. }
  541. }
  542. void StreamCoder::setChannelLayout(uint64_t layout)
  543. {
  544. if (context && !isOpenedFlag && layout > 0)
  545. {
  546. context->channel_layout = layout;
  547. // Make channels and channel_layout sync
  548. if (context->channels == 0 ||
  549. av_get_default_channel_layout(context->channels) != layout)
  550. {
  551. context->channels = av_get_channel_layout_nb_channels(layout);
  552. }
  553. }
  554. }
  555. void StreamCoder::setAudioFrameSize(int frameSize)
  556. {
  557. if (context)
  558. context->frame_size = frameSize;
  559. }
  560. void StreamCoder::setDefaultAudioFrameSize(int frameSize)
  561. {
  562. defaultAudioFrameSize = frameSize;
  563. }
  564. void StreamCoder::setFlags(int32_t flags)
  565. {
  566. if (context)
  567. context->flags = flags;
  568. }
  569. void StreamCoder::addFlags(int32_t flags)
  570. {
  571. if (context)
  572. context->flags |= flags;
  573. }
  574. void StreamCoder::clearFlags(int32_t flags)
  575. {
  576. if (context)
  577. context->flags &= ~flags;
  578. }
  579. int32_t StreamCoder::getFlags()
  580. {
  581. return (context ? context->flags : 0);
  582. }
  583. ssize_t StreamCoder::decodeVideo(const FramePtr &outFrame, const PacketPtr &inPacket, size_t offset)
  584. {
  585. return decodeCommon(outFrame, inPacket, offset, avcodec_decode_video2);
  586. }
  587. ssize_t StreamCoder::encodeVideo(const PacketPtr &outPacket, const VideoFramePtr &inFrame, const EncodedPacketHandler &onPacketHandler)
  588. {
  589. if (inFrame->getPixelFormat() != getPixelFormat())
  590. {
  591. cerr << "Frame does not have same PixelFormat to coder: " << av_get_pix_fmt_name(inFrame->getPixelFormat()) << endl;
  592. return -1;
  593. }
  594. if (inFrame->getWidth() != getWidth())
  595. {
  596. cerr << "Frame does not have same Width to coder\n";
  597. return -1;
  598. }
  599. if (inFrame->getHeight() != getHeight())
  600. {
  601. cerr << "Frame does not have same Height to coder\n";
  602. return -1;
  603. }
  604. return encodeCommon(outPacket, inFrame, avcodec_encode_video2, onPacketHandler);
  605. }
  606. ssize_t StreamCoder::decodeAudio(const FramePtr &outFrame, const PacketPtr &inPacket, size_t offset)
  607. {
  608. return decodeCommon(outFrame, inPacket, offset, avcodec_decode_audio4);
  609. }
  610. ssize_t StreamCoder::encodeAudio(const PacketPtr &outPacket, const FramePtr &inFrame, const EncodedPacketHandler &onPacketHandler)
  611. {
  612. // TODO: additional checks like encodeVideo()
  613. return encodeCommon(outPacket, inFrame, avcodec_encode_audio2, onPacketHandler);
  614. }
  615. bool StreamCoder::isValidForEncode()
  616. {
  617. if (!isOpenedFlag)
  618. {
  619. cerr << "You must open coder before encoding\n";
  620. return false;
  621. }
  622. if (!context)
  623. {
  624. cerr << "Codec context does not exists\n";
  625. return false;
  626. }
  627. // if (context->codec_type != AVMEDIA_TYPE_VIDEO)
  628. // {
  629. // cerr << "Attempting to encode video with non video coder\n";
  630. // return false;
  631. // }
  632. if (direction == DECODING)
  633. {
  634. cerr << "Decoding coder does not valid for encoding\n";
  635. return false;
  636. }
  637. if (!codec)
  638. {
  639. cerr << "Codec does not set\n";
  640. return false;
  641. }
  642. if (!codec->canEncode())
  643. {
  644. cerr << "Codec can't be used for Encode\n";
  645. return false;
  646. }
  647. fakeCurrPts = AV_NOPTS_VALUE;
  648. fakeNextPts = AV_NOPTS_VALUE;
  649. return true;
  650. }
  651. } // ::av