/******************************************************************************* * plugins/VOIP/gui/VideoProcessor.h * * * * Copyright (C) 2012 by Retroshare Team <retroshare.project@gmail.com> * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * * * * You should have received a copy of the GNU Affero General Public License * * along with this program. If not, see <https://www.gnu.org/licenses/>. * * * *******************************************************************************/ #pragma once #include <stdint.h> #include <QImage> #include "interface/rsVOIP.h" extern "C" { #include <libavcodec/avcodec.h> } class QVideoOutputDevice ; class VideoCodec { public: virtual bool encodeData(const QImage& Image, uint32_t size_hint, RsVOIPDataChunk& chunk) = 0; virtual bool decodeData(const RsVOIPDataChunk& chunk,QImage& image) = 0; protected: static const uint32_t HEADER_SIZE = 0x04 ; }; // Now derive various image encoding/decoding algorithms. // class JPEGVideo: public VideoCodec { public: JPEGVideo() ; protected: virtual bool encodeData(const QImage& Image, uint32_t target_encoding_bitrate, RsVOIPDataChunk& chunk) ; virtual bool decodeData(const RsVOIPDataChunk& chunk,QImage& image) ; static const uint32_t JPEG_VIDEO_FLAGS_DIFFERENTIAL_FRAME = 0x0001 ; private: QImage _decoded_reference_frame ; QImage _encoded_reference_frame ; uint32_t _encoded_ref_frame_max_distance ; // max distance between two reference frames. uint32_t _encoded_ref_frame_count ; }; struct AVCodec ; struct AVCodecContext ; struct AVFrame ; struct AVPacket ; class FFmpegVideo: public VideoCodec { public: FFmpegVideo() ; ~FFmpegVideo() ; protected: virtual bool encodeData(const QImage& Image, uint32_t target_encoding_bitrate, RsVOIPDataChunk& chunk) ; virtual bool decodeData(const RsVOIPDataChunk& chunk,QImage& image) ; private: AVCodec *encoding_codec; AVCodec *decoding_codec; AVCodecContext *encoding_context; AVCodecContext *decoding_context; AVFrame *encoding_frame_buffer ; AVFrame *decoding_frame_buffer ; AVPacket decoding_buffer; uint64_t encoding_frame_count ; #ifdef DEBUG_MPEG_VIDEO FILE *encoding_debug_file ; #endif }; // This class decodes video from a stream. It keeps a queue of // decoded frame that needs to be retrieved using the getNextImage() method. // class VideoProcessor { public: VideoProcessor() ; virtual ~VideoProcessor() ; enum CodecId { VIDEO_PROCESSOR_CODEC_ID_UNKNOWN = 0x0000, VIDEO_PROCESSOR_CODEC_ID_JPEG_VIDEO = 0x0001, VIDEO_PROCESSOR_CODEC_ID_DDWT_VIDEO = 0x0002, VIDEO_PROCESSOR_CODEC_ID_MPEG_VIDEO = 0x0003 }; // ===================================================================================== // =------------------------------------ DECODING -------------------------------------= // ===================================================================================== // Gets the next image to be displayed. Once returned, the image should // be cleared from the incoming queue. // void setDisplayTarget(QVideoOutputDevice *odev) { _decoded_output_device = odev ; } virtual void receiveEncodedData(const RsVOIPDataChunk& chunk) ; // returns the current (measured) frame rate in bytes per second. // uint32_t currentBandwidthIn() const { return _estimated_bandwidth_in ; } private: QVideoOutputDevice *_decoded_output_device ; std::list<QImage> _decoded_image_queue ; //time_t _lastTimeToShowFrame ; // ===================================================================================== // =------------------------------------ ENCODING -------------------------------------= // ===================================================================================== public: // Takes the next image to be encoded. // bool processImage(const QImage& Image) ; bool encodedPacketReady() const { return !_encoded_out_queue.empty() ; } bool nextEncodedPacket(RsVOIPDataChunk& ) ; // Used to tweak the compression ratio so that the video can stream ok. // void setMaximumBandwidth(uint32_t bytes_per_second) ; void setInternalFrameSize(QSize) ; // returns the current encoding frame rate in bytes per second. // uint32_t currentBandwidthOut() const { return _estimated_bandwidth_out ; } protected: std::list<RsVOIPDataChunk> _encoded_out_queue ; QSize _encoded_frame_size ; // ===================================================================================== // =------------------------------------- Codecs --------------------------------------= // ===================================================================================== JPEGVideo _jpeg_video_codec ; FFmpegVideo _mpeg_video_codec ; uint16_t _encoding_current_codec ; time_t _last_bw_estimate_in_TS; time_t _last_bw_estimate_out_TS; uint32_t _total_encoded_size_in ; uint32_t _total_encoded_size_out ; float _estimated_bandwidth_in ; float _estimated_bandwidth_out ; float _target_bandwidth_out ; RsMutex vpMtx ; };