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