video_input.h 3.62 KB
Newer Older
1
/*
2
 *  Copyright (C) 2004-2020 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 9 10 11 12 13 14 15 16 17 18 19
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  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_stream.h"
28
#include "media/media_device.h" // DeviceParams
29
#include "media/video/video_base.h"
30

Rafaël Carré's avatar
Rafaël Carré committed
31
#include <map>
32
#include <atomic>
33
#include <future>
34
#include <string>
35 36
#include <mutex>
#include <condition_variable>
37
#include <array>
38

39 40 41 42
#if __APPLE__
#import "TargetConditionals.h"
#endif

Adrien Béraud's avatar
Adrien Béraud committed
43
namespace jami {
44
class MediaDecoder;
45 46
}

Adrien Béraud's avatar
Adrien Béraud committed
47
namespace jami { namespace video {
48

49 50
class SinkClient;

51
enum class VideoInputMode {ManagedByClient, ManagedByDaemon, Undefined};
52

53
class VideoInput : public VideoGenerator, public std::enable_shared_from_this<VideoInput>
54 55
{
public:
56
    VideoInput(VideoInputMode inputMode = VideoInputMode::Undefined);
57
    ~VideoInput();
58 59

    // as VideoGenerator
Adrien Béraud's avatar
Adrien Béraud committed
60 61 62
    const std::string& getName() const {
      return currentResource_;
    }
63 64
    int getWidth() const;
    int getHeight() const;
65
    AVPixelFormat getPixelFormat() const;
66
    const DeviceParams& getParams() const;
67
    MediaStream getInfo() const;
68

69
    std::shared_future<DeviceParams> switchInput(const std::string& resource);
70
#if VIDEO_CLIENT_INPUT
71
    /*
72 73
     * these functions are used to pass buffer from/to the daemon
     * on the Android and UWP builds
74 75 76 77
     */
    void* obtainFrame(int length);
    void releaseFrame(void *frame);
#endif
78

79
private:
80
    NON_COPYABLE(VideoInput);
81

82
    std::string currentResource_;
83
    std::atomic<bool> switchPending_ = {false};
84
    std::atomic_bool  isStopped_ = {false};
85

Guillaume Roguez's avatar
Guillaume Roguez committed
86
    DeviceParams decOpts_;
87
    std::promise<DeviceParams> foundDecOpts_;
88
    std::shared_future<DeviceParams> futureDecOpts_;
89
    bool emulateRate_       = false;
90

91 92 93
    std::atomic_bool decOptsFound_ {false};
    void foundDecOpts(const DeviceParams& params);

Guillaume Roguez's avatar
Guillaume Roguez committed
94
    void clearOptions();
95

96
    // true if decOpts_ is ready to use, false if using promise/future
97 98
    bool initCamera(const std::string& device);
    bool initX11(std::string display);
99
    bool initAVFoundation(const std::string& display);
100
    bool initFile(std::string path);
101
    bool initGdiGrab(const std::string& params);
102

103 104 105 106 107 108 109 110 111 112 113
    bool isCapturing() const noexcept;
    void startLoop();

    void switchDevice();
    bool capturing_ {false};
    void createDecoder();
    void deleteDecoder();
    std::unique_ptr<MediaDecoder> decoder_;
    std::shared_ptr<SinkClient> sink_;
    ThreadLoop loop_;

114
    // for ThreadLoop
115 116 117
    bool setup();
    void process();
    void cleanup();
Rafaël Carré's avatar
Rafaël Carré committed
118

119
    bool captureFrame();
120

121 122 123
    int rotation_ {0};
    std::shared_ptr<AVBufferRef> displayMatrix_;
    void setRotation(int angle);
124 125 126 127
    VideoInputMode inputMode_;
    inline bool videoManagedByClient() const {
         return inputMode_ == VideoInputMode::ManagedByClient;
    }
128
};
129

Adrien Béraud's avatar
Adrien Béraud committed
130
}} // namespace jami::video