LCOV - code coverage report
Current view: top level - src/media/video - video_input.h (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 5 5 100.0 %
Date: 2024-03-28 08:00:27 Functions: 3 3 100.0 %

          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: Vivien Didelot <vivien.didelot@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             : #pragma once
      24             : 
      25             : #include "noncopyable.h"
      26             : #include "threadloop.h"
      27             : #include "media/media_stream.h"
      28             : #include "media/media_device.h" // DeviceParams
      29             : #include "media/video/video_base.h"
      30             : #include "media/media_codec.h"
      31             : 
      32             : #include <map>
      33             : #include <atomic>
      34             : #include <future>
      35             : #include <string>
      36             : #include <mutex>
      37             : #include <condition_variable>
      38             : #include <array>
      39             : 
      40             : #if __APPLE__
      41             : #import "TargetConditionals.h"
      42             : #endif
      43             : 
      44             : namespace jami {
      45             : class MediaDecoder;
      46             : class MediaDemuxer;
      47             : } // namespace jami
      48             : 
      49             : namespace jami {
      50             : namespace video {
      51             : 
      52             : class SinkClient;
      53             : 
      54             : enum class VideoInputMode { ManagedByClient, ManagedByDaemon, Undefined };
      55             : 
      56             : class VideoInput : public VideoGenerator
      57             : {
      58             : public:
      59             :     VideoInput(VideoInputMode inputMode = VideoInputMode::Undefined,
      60             :                const std::string& resource = "local",
      61             :                const std::string& sink = "");
      62             :     ~VideoInput();
      63             : 
      64             :     // as VideoGenerator
      65             :     const std::string& getName() const { return resource_; }
      66             :     int getWidth() const;
      67             :     int getHeight() const;
      68             :     AVPixelFormat getPixelFormat() const;
      69             : 
      70             :     const DeviceParams& getConfig() const {
      71             :         return decOpts_;
      72             :     }
      73         116 :     std::shared_future<DeviceParams> getParams() const {
      74         116 :         return futureDecOpts_;
      75             :     }
      76             : 
      77             :     MediaStream getInfo() const;
      78             : 
      79             :     void setSink(const std::string& sinkId);
      80             :     void updateStartTime(int64_t startTime);
      81             :     void configureFilePlayback(const std::string& path,
      82             :                                std::shared_ptr<MediaDemuxer>& demuxer,
      83             :                                int index);
      84             :     void flushBuffers();
      85          20 :     void setPaused(bool paused) { paused_ = paused; }
      86             :     void setSeekTime(int64_t time);
      87             :     void setupSink(const int width, const int height);
      88             :     void stopSink();
      89             : 
      90             :     void setRecorderCallback(const std::function<void(const MediaStream& ms)>& cb);
      91             : 
      92             : #if VIDEO_CLIENT_INPUT
      93             :     /*
      94             :      * these functions are used to pass buffer from/to the daemon
      95             :      * on the Android and UWP builds
      96             :      */
      97             :     void* obtainFrame(int length);
      98             :     void releaseFrame(void* frame);
      99             : #else
     100             :     void stopInput();
     101             : #endif
     102             : 
     103             :     void setSuccessfulSetupCb(const std::function<void(MediaType, bool)>& cb)
     104             :     {
     105             :         onSuccessfulSetup_ = cb;
     106             :     }
     107             : 
     108             :     /**
     109             :      * Restart stopped video input
     110             :      * @note if a media is removed, then re-added in a conference, the loop will be stopped
     111             :      * and this input must be restarted
     112             :      */
     113             :     void restart();
     114             : 
     115             : private:
     116             :     NON_COPYABLE(VideoInput);
     117             : 
     118             :     std::shared_future<DeviceParams> switchInput(const std::string& resource);
     119             : 
     120             :     std::string resource_;
     121             :     std::atomic<bool> switchPending_ = {false};
     122             :     std::atomic_bool isStopped_ = {false};
     123             : 
     124             :     DeviceParams decOpts_;
     125             :     std::promise<DeviceParams> foundDecOpts_;
     126             :     std::shared_future<DeviceParams> futureDecOpts_;
     127             :     bool emulateRate_ = false;
     128             : 
     129             :     std::atomic_bool decOptsFound_ {false};
     130             :     void foundDecOpts(const DeviceParams& params);
     131             : 
     132             :     void clearOptions();
     133             : 
     134             :     // true if decOpts_ is ready to use, false if using promise/future
     135             :     bool initCamera(const std::string& device);
     136             :     bool initFile(std::string path);
     137             : 
     138             : #ifdef __APPLE__
     139             :     bool initAVFoundation(const std::string& display);
     140             : #elif defined(WIN32)
     141             :     bool initWindowsGrab(const std::string& display);
     142             : #else
     143             :     bool initLinuxGrab(const std::string& display);
     144             : #endif
     145             : 
     146             :     bool isCapturing() const noexcept;
     147             :     void startLoop();
     148             : 
     149             :     void switchDevice();
     150             :     bool capturing_ {false};
     151             :     void createDecoder();
     152             :     void deleteDecoder();
     153             :     std::unique_ptr<MediaDecoder> decoder_;
     154             :     std::shared_ptr<SinkClient> sink_;
     155             :     ThreadLoop loop_;
     156             : 
     157             :     // for ThreadLoop
     158             :     bool setup();
     159             :     void process();
     160             :     void cleanup();
     161             : 
     162             :     bool captureFrame();
     163             : 
     164             :     int rotation_ {0};
     165             :     std::shared_ptr<AVBufferRef> displayMatrix_;
     166             :     void setRotation(int angle);
     167             :     VideoInputMode inputMode_;
     168         366 :     inline bool videoManagedByClient() const
     169             :     {
     170         366 :         return inputMode_ == VideoInputMode::ManagedByClient;
     171             :     }
     172             :     bool playingFile_ = false;
     173             :     std::atomic_bool paused_ {true};
     174             : 
     175             :     std::function<void(MediaType, bool)> onSuccessfulSetup_;
     176             :     std::function<void(const MediaStream& ms)> recorderCallback_;
     177             : };
     178             : 
     179             : } // namespace video
     180             : } // namespace jami

Generated by: LCOV version 1.14