hc
2023-11-06 15ade055295d13f95d49e3d99b09f3bbfb4a43e7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright 2019 Fuzhou Rockchip Electronics Co., Ltd. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
#ifndef EASYMEDIA_LIVE555_MEDIA_INPUT_HH_
#define EASYMEDIA_LIVE555_MEDIA_INPUT_HH_
 
#include <functional>
#include <list>
#include <memory>
#include <type_traits>
 
#include <liveMedia/MediaSink.hh>
 
#include "lock.h"
#include "media_type.h"
 
namespace easymedia {
 
class MediaBuffer;
class VideoFramedSource;
class CommonFramedSource;
using ListReductionPtr = std::add_pointer<void(
    void *userdata, std::list<std::shared_ptr<MediaBuffer>> &mb_list)>::type;
 
// using StartStreamCallback = std::add_pointer<void(void)>::type;
typedef std::function<void()> StartStreamCallback;
 
class Source {
public:
  Source();
  ~Source();
  bool Init(ListReductionPtr func = nullptr);
  void Push(std::shared_ptr<easymedia::MediaBuffer> &);
  std::shared_ptr<MediaBuffer> Pop();
  int GetReadFd() { return wakeFds[0]; }
  int GetWriteFd() { return wakeFds[1]; }
  Boolean GetReadFdStatus() { return m_read_fd_status; }
  void CloseReadFd();
  unsigned GetCachedBufSize() { return m_cached_buffers_size; }
  void SetCachedBufSize(size_t one_buf_size);
 
private:
  std::list<std::shared_ptr<MediaBuffer>> cached_buffers;
  ConditionLockMutex mtx;
  ListReductionPtr reduction;
  int wakeFds[2]; // Live555's EventTrigger is poor for multithread, use fds
  unsigned m_cached_buffers_size;
  Boolean m_read_fd_status;
};
 
class Live555MediaInput : public Medium {
public:
  static Live555MediaInput *createNew(UsageEnvironment &env);
  FramedSource *videoSource(CodecType c_type);
  FramedSource *audioSource();
  FramedSource *muxerSource();
  void Start(UsageEnvironment &env);
  void Stop(UsageEnvironment &env);
 
  void PushNewVideo(std::shared_ptr<MediaBuffer> &buffer);
  void PushNewAudio(std::shared_ptr<MediaBuffer> &buffer);
  void PushNewMuxer(std::shared_ptr<MediaBuffer> &buffer);
 
  void SetStartVideoStreamCallback(const StartStreamCallback &cb);
  StartStreamCallback GetStartVideoStreamCallback();
  void SetStartAudioStreamCallback(const StartStreamCallback &cb);
  StartStreamCallback GetStartAudioStreamCallback();
 
  unsigned getMaxIdrSize();
 
protected:
  virtual ~Live555MediaInput();
 
private:
  Live555MediaInput(UsageEnvironment &env);
 
  std::list<Source *> video_list;
  std::list<Source *> audio_list;
  std::list<Source *> muxer_list;
  volatile bool connecting;
 
  StartStreamCallback video_callback;
  StartStreamCallback audio_callback;
 
  ConditionLockMutex video_callback_mtx;
  ConditionLockMutex audio_callback_mtx;
 
  friend class VideoFramedSource;
  friend class CommonFramedSource;
  unsigned m_max_idr_size;
};
 
class ListSource : public FramedSource {
protected:
  ListSource(UsageEnvironment &env, Source &source)
      : FramedSource(env), fSource(source) {}
  virtual ~ListSource() {
    if (fSource.GetReadFd() >= 0)
      envir().taskScheduler().turnOffBackgroundReadHandling(
          fSource.GetReadFd());
    fSource.CloseReadFd();
  }
 
  virtual bool readFromList(bool flush = false) = 0;
  virtual void flush();
 
  Source &fSource;
 
private: // redefined virtual functions:
  virtual void doGetNextFrame();
  virtual void doStopGettingFrames();
 
  static void incomingDataHandler(ListSource *source, int mask);
  void incomingDataHandler1();
};
 
class VideoFramedSource : public ListSource {
public:
  VideoFramedSource(UsageEnvironment &env, Source &source);
  virtual ~VideoFramedSource();
 
  void SetCodecType(CodecType type) { codec_type = type; }
  CodecType GetCodecType() { return codec_type; }
 
protected: // redefined virtual functions:
  virtual bool readFromList(bool flush = false);
  bool got_iframe;
  CodecType codec_type;
};
 
class CommonFramedSource : public ListSource {
public:
  CommonFramedSource(UsageEnvironment &env, Source &source);
  virtual ~CommonFramedSource();
 
protected: // redefined virtual functions:
  virtual bool readFromList(bool flush = false);
};
 
// Functions to set the optimal buffer size for RTP sink objects.
// These should be called before each RTPSink is created.
#define AUDIO_MAX_FRAME_SIZE 204800
#define VIDEO_MAX_FRAME_SIZE (1920 * 1080 * 2)
inline void setAudioRTPSinkBufferSize() {
  OutPacketBuffer::maxSize = AUDIO_MAX_FRAME_SIZE;
}
inline void setVideoRTPSinkBufferSize() {
  OutPacketBuffer::maxSize = VIDEO_MAX_FRAME_SIZE;
}
 
} // namespace easymedia
 
#endif // #ifndef EASYMEDIA_LIVE555_MEDIA_INPUT_HH_