decoder.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #pragma once
  2. #include <bitset>
  3. #include <unordered_map>
  4. #include "seekable_buffer.h"
  5. #include "stream.h"
  6. #if defined(_MSC_VER)
  7. #include <BaseTsd.h>
  8. using ssize_t = SSIZE_T;
  9. #endif
  10. namespace ffmpeg {
  11. /**
  12. * Class uses FFMPEG library to decode media streams.
  13. * Media bytes can be explicitly provided through read-callback
  14. * or fetched internally by FFMPEG library
  15. */
  16. class Decoder : public MediaDecoder {
  17. public:
  18. Decoder();
  19. ~Decoder() override;
  20. // MediaDecoder overrides
  21. bool init(
  22. const DecoderParameters& params,
  23. DecoderInCallback&& in,
  24. std::vector<DecoderMetadata>* metadata) override;
  25. int decode_all(const DecoderOutCallback& callback) override;
  26. void shutdown() override;
  27. void interrupt() override;
  28. protected:
  29. // function does actual work, derived class calls it in working thread
  30. // periodically. On success method returns 0, ENOADATA on EOF, ETIMEDOUT if
  31. // no frames got decoded in the specified timeout time, and error on
  32. // unrecoverable error.
  33. int getFrame(size_t workingTimeInMs = 100);
  34. // Derived class must override method and consume the provided message
  35. virtual void push(DecoderOutputMessage&& buffer) = 0;
  36. // Fires on init call
  37. virtual void onInit() {}
  38. public:
  39. // C-style FFMPEG API requires C/static methods for callbacks
  40. static void logFunction(void* avcl, int level, const char* cfmt, va_list vl);
  41. static int shutdownFunction(void* ctx);
  42. static int readFunction(void* opaque, uint8_t* buf, int size);
  43. static int64_t seekFunction(void* opaque, int64_t offset, int whence);
  44. // can be called by any classes or API
  45. static void initOnce();
  46. int* getPrintPrefix() {
  47. return &printPrefix;
  48. }
  49. private:
  50. // mark below function for a proper invocation
  51. bool enableLogLevel(int level) const;
  52. void logCallback(int level, const std::string& message);
  53. int readCallback(uint8_t* buf, int size);
  54. int64_t seekCallback(int64_t offset, int whence);
  55. int shutdownCallback();
  56. bool openStreams(std::vector<DecoderMetadata>* metadata);
  57. Stream* findByIndex(int streamIndex) const;
  58. Stream* findByType(const MediaFormat& format) const;
  59. int processPacket(
  60. Stream* stream,
  61. AVPacket* packet,
  62. bool* gotFrame,
  63. bool* hasMsg,
  64. bool fastSeek = false);
  65. void flushStreams();
  66. void cleanUp();
  67. protected:
  68. DecoderParameters params_;
  69. private:
  70. SeekableBuffer seekableBuffer_;
  71. int printPrefix{1};
  72. std::atomic<bool> interrupted_{false};
  73. AVFormatContext* inputCtx_{nullptr};
  74. AVIOContext* avioCtx_{nullptr};
  75. std::unordered_map<ssize_t, std::unique_ptr<Stream>> streams_;
  76. std::bitset<64> inRange_;
  77. };
  78. } // namespace ffmpeg