#ifndef ENCODER_VIDEO #define ENCODER_VIDEO #include #include #include #include #include #include "headers_ffmpeg.h" #include "ring_buffer.h" #include "encoder_video_define.h" namespace am { typedef std::function cb_264_data; typedef std::function cb_264_error; class encoder_video { public: encoder_video(); virtual ~encoder_video(); virtual int init( int pic_width, int pic_height, int frame_rate, int bit_rate, int qb, int key_pic_sec = 2) = 0; virtual int get_extradata_size() = 0; virtual const uint8_t *get_extradata() = 0; inline void registe_cb(cb_264_data on_data, cb_264_error on_error) { _on_data = on_data; _on_error = on_error; } inline const AVRational &get_time_base() { return _time_base; }; virtual int start(); virtual void stop(); virtual int put(const uint8_t *data, int data_len, AVFrame *frame); virtual AVCodecID get_codec_id() = 0; // Ring buffer stats/config helpers inline size_t rb_dropped_frames() const { return _ring_buffer ? _ring_buffer->dropped_frames() : 0; } inline size_t rb_pending_frames() const { return _ring_buffer ? _ring_buffer->get_pending_frames() : 0; } inline size_t rb_max_frames() const { return _ring_buffer ? _ring_buffer->max_frames() : 0; } inline void rb_set_max_frames(size_t max_frames) { if (_ring_buffer) _ring_buffer->set_max_frames(max_frames); } inline void rb_reset_dropped() { if (_ring_buffer) _ring_buffer->reset_dropped_frames(); } protected: virtual void cleanup() = 0; virtual void encode_loop() = 0; protected: ENCODER_VIDEO_ID _encoder_id; ENCODER_VIDEO_TYPES _encoder_type; cb_264_data _on_data; cb_264_error _on_error; ring_buffer *_ring_buffer; AVRational _time_base; std::atomic_bool _inited; std::atomic_bool _running; std::thread _thread; std::mutex _mutex; std::condition_variable _cond_var; bool _cond_notify; }; } // namespace am #endif // !ENCODER_VIDEO