mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
176 lines
6.3 KiB
C++
176 lines
6.3 KiB
C++
/*******************************************************************************
|
|
* 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 ;
|
|
};
|
|
|