Line data Source code
1 : /* 2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc. 3 : * 4 : * Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com> 5 : * Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> 6 : * Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com> 7 : * 8 : * This program is free software; you can redistribute it and/or modify 9 : * it under the terms of the GNU General Public License as published by 10 : * the Free Software Foundation; either version 3 of the License, or 11 : * (at your option) any later version. 12 : * 13 : * This program is distributed in the hope that it will be useful, 14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : * GNU General Public License for more details. 17 : * 18 : * You should have received a copy of the GNU General Public License 19 : * along with this program; if not, write to the Free Software 20 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 21 : */ 22 : 23 : #ifndef _VIDEO_RECEIVE_THREAD_H_ 24 : #define _VIDEO_RECEIVE_THREAD_H_ 25 : 26 : #include "video_base.h" 27 : #include "media/media_codec.h" 28 : #include "media/media_io_handle.h" 29 : #include "media/media_codec.h" 30 : #include "media/media_device.h" 31 : #include "media/media_stream.h" 32 : #include "threadloop.h" 33 : #include "noncopyable.h" 34 : #include "media/libav_utils.h" 35 : 36 : #include <functional> 37 : #include <map> 38 : #include <string> 39 : #include <climits> 40 : #include <sstream> 41 : #include <memory> 42 : 43 : namespace jami { 44 : class SocketPair; 45 : class MediaDecoder; 46 : } // namespace jami 47 : 48 : namespace jami { 49 : namespace video { 50 : 51 : class SinkClient; 52 : 53 : class VideoReceiveThread : public VideoGenerator 54 : { 55 : public: 56 : VideoReceiveThread(const std::string& id, bool useSink, const std::string& sdp, uint16_t mtu); 57 : ~VideoReceiveThread(); 58 : 59 : void startLoop(); 60 : void stopLoop(); 61 : void decodeFrame(); 62 : void addIOContext(SocketPair& socketPair); 63 144 : void setRequestKeyFrameCallback(std::function<void(void)> cb) 64 : { 65 144 : keyFrameRequestCallback_ = std::move(cb); 66 144 : }; 67 : void startSink(); 68 : void stopSink(); 69 146 : std::shared_ptr<SinkClient>& getSink() { return sink_; } 70 : 71 : // as VideoGenerator 72 : int getWidth() const; 73 : int getHeight() const; 74 : AVPixelFormat getPixelFormat() const; 75 : MediaStream getInfo() const; 76 : 77 : /** 78 : * Set angle of rotation to apply to the video by the decoder 79 : * 80 : * @param angle Angle of rotation in degrees (counterclockwise) 81 : */ 82 : void setRotation(int angle); 83 : 84 144 : void setSuccessfulSetupCb(const std::function<void(MediaType, bool)>& cb) 85 : { 86 144 : onSuccessfulSetup_ = cb; 87 144 : } 88 : 89 : void setRecorderCallback( 90 : const std::function<void(const MediaStream& ms)>& cb); 91 : 92 : private: 93 : NON_COPYABLE(VideoReceiveThread); 94 : 95 : DeviceParams args_; 96 : 97 : /*-------------------------------------------------------------*/ 98 : /* These variables should be used in thread (i.e. run()) only! */ 99 : /*-------------------------------------------------------------*/ 100 : std::unique_ptr<MediaDecoder> videoDecoder_; 101 : int dstWidth_ {0}; 102 : int dstHeight_ {0}; 103 : const std::string id_; 104 : bool useSink_; 105 : std::istringstream stream_; 106 : MediaIOHandle sdpContext_; 107 : std::unique_ptr<MediaIOHandle> demuxContext_; 108 : std::shared_ptr<SinkClient> sink_; 109 : bool isVideoConfigured_ {false}; 110 : uint16_t mtu_; 111 : int rotation_ {0}; 112 : 113 : std::mutex rotationMtx_; 114 : libav_utils::AVBufferPtr displayMatrix_; 115 : 116 : static int interruptCb(void* ctx); 117 : static int readFunction(void* opaque, uint8_t* buf, int buf_size); 118 : bool configureVideoOutput(); 119 : 120 : ThreadLoop loop_; 121 : 122 : // used by ThreadLoop 123 : bool setup(); 124 : void process(); 125 : void cleanup(); 126 : 127 : std::function<void(void)> keyFrameRequestCallback_; 128 : std::function<void(MediaType, bool)> onSuccessfulSetup_; 129 : std::function<void(const MediaStream& ms)> recorderCallback_; 130 : }; 131 : 132 : } // namespace video 133 : } // namespace jami 134 : 135 : #endif // _VIDEO_RECEIVE_THREAD_H_