stream.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #pragma once
  2. #include <atomic>
  3. #include "defs.h"
  4. #include "time_keeper.h"
  5. namespace ffmpeg {
  6. /**
  7. * Class uses FFMPEG library to decode one media stream (audio or video).
  8. */
  9. class Stream {
  10. public:
  11. Stream(
  12. AVFormatContext* inputCtx,
  13. MediaFormat format,
  14. bool convertPtsToWallTime,
  15. int64_t loggingUuid);
  16. virtual ~Stream();
  17. // returns 0 - on success or negative error
  18. // num_threads sets up the codec context for multithreading if needed
  19. // default is set to single thread in order to not break BC
  20. int openCodec(std::vector<DecoderMetadata>* metadata, int num_threads = 1);
  21. // returns 1 - if packet got consumed, 0 - if it's not, and < 0 on error
  22. int decodePacket(
  23. const AVPacket* packet,
  24. DecoderOutputMessage* out,
  25. bool headerOnly,
  26. bool* hasMsg);
  27. // returns stream index
  28. int getIndex() const {
  29. return format_.stream;
  30. }
  31. // returns 1 - if message got a payload, 0 - if it's not, and < 0 on error
  32. int flush(DecoderOutputMessage* out, bool headerOnly);
  33. // return media format
  34. MediaFormat getMediaFormat() const {
  35. return format_;
  36. }
  37. protected:
  38. virtual int initFormat() = 0;
  39. // returns number processed bytes from packet, or negative error
  40. virtual int analyzePacket(const AVPacket* packet, bool* gotFrame);
  41. // returns number processed bytes from packet, or negative error
  42. virtual int copyFrameBytes(ByteStorage* out, bool flush) = 0;
  43. // sets output format
  44. virtual void setHeader(DecoderHeader* header, bool flush);
  45. // set frame pts
  46. virtual void setFramePts(DecoderHeader* header, bool flush);
  47. // finds codec
  48. virtual AVCodec* findCodec(AVCodecParameters* params);
  49. private:
  50. // returns 1 - if message got a payload, 0 - if it's not, and < 0 on error
  51. int getMessage(DecoderOutputMessage* out, bool flush, bool headerOnly);
  52. protected:
  53. AVFormatContext* const inputCtx_;
  54. MediaFormat format_;
  55. const bool convertPtsToWallTime_;
  56. int64_t loggingUuid_;
  57. AVCodecContext* codecCtx_{nullptr};
  58. AVFrame* frame_{nullptr};
  59. std::atomic<size_t> numGenerator_{0};
  60. TimeKeeper keeper_;
  61. // estimated next frame pts for flushing the last frame
  62. int64_t nextPts_{0};
  63. double fps_{30.};
  64. // this is a dumb conservative limit; ideally we'd use
  65. // int max_threads = at::get_num_threads(); but this would cause
  66. // fb sync to fail as it would add dependency to ATen to the decoder API
  67. const int max_threads = 12;
  68. };
  69. } // namespace ffmpeg