11/**
2- * @file video_capture/ug_input.cpp
2+ * @file video_capture/ug_input.c
33 * @author Martin Pulec <pulec@cesnet.cz>
44 */
55/*
3535 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3636 */
3737
38- #include < cassert> // for assert
39- #include < cctype> // for isdigit
40- #include < cstdint> // for uint16_t
41- #include < cstdio> // for printf, snprintf
42- #include < cstdlib> // for free
43- #include < cstring> // for strlen, strchr, strcmp, strdup
44- #include < memory> // for unique_ptr
45- #include < mutex> // for mutex, lock_guard
46- #include < queue> // for queue
47- #include < string> // for basic_string, stoi, string
48- #include < utility> // for pair
38+ #include <assert.h> // for assert
39+ #include <ctype.h> // for isdigit
40+ #include <pthread.h> // for pthread_mutex_unlock, pthread_mute...
41+ #include <stdint.h> // for uint16_t
42+ #include <stdio.h> // for printf, snprintf
43+ #include <stdlib.h> // for free
44+ #include <string.h> // for strlen, strchr, strcmp, strdup
4945
5046#include "audio/audio.h" // for audio_options, AUDIO_OPTIONS_INIT
5147#include "audio/types.h" // for AUDIO_FRAME_DISPOSE
48+ #include "compat/c23.h" // IWYU pragma: keep
5249#include "debug.h" // for LOG_LEVEL_ERROR, LOG_LEVEL_WARNING
5350#include "host.h" // for common_opts, COMMON_OPTS_INIT
5451#include "lib_common.h" // for REGISTER_MODULE, library_class
5552#include "types.h" // for VIDEO_CODEC_NONE, codec_t, device_...
5653#include "utils/color_out.h" // for TBOLD, color_printf, TRED
54+ #include "utils/list.h" // for simple_linked_list
5755#include "utils/macros.h" // for to_fourcc, IS_KEY_PREFIX, snprintf_ch
5856#include "video_capture.h" // for VIDCAP_INIT_FAIL, VIDCAP_INIT_NOERR
5957#include "video_capture_params.h" // for vidcap_params_get_fmt, vidcap_para...
6361#include "video_frame.h" // for VIDEO_FRAME_DISPOSE, vf_free
6462#include "video_rxtx.hpp" // for video_rxtx, vrxtx_params, VRXTX_INIT
6563
64+ struct vidcap_params ;
65+
6666#define MAGIC to_fourcc('V', 'C', 'u', 'i')
6767#define MOD_NAME "[ug_input] "
68- static constexpr int MAX_QUEUE_SIZE = 2 ;
69-
70- using std::lock_guard;
71- using std::mutex;
72- using std::pair;
73- using std::queue;
74- using std::stoi;
75- using std::string;
76- using std::unique_ptr;
77-
78- struct ug_input_state final {
79- uint32_t magic = MAGIC;
80- mutex lock;
81- queue<pair<struct video_frame *, struct audio_frame *>> frame_queue;
82- struct display *display = nullptr ;
83-
84- unique_ptr<struct video_rxtx > video_rxtx;
85- struct state_audio *audio = nullptr ;
68+ static const int MAX_QUEUE_SIZE = 2 ;
69+
70+ struct av_frame {
71+ struct video_frame * vframe ;
72+ struct audio_frame * aframe ;
73+ };
74+
75+ struct ug_input_state {
76+ uint32_t magic ;
77+ pthread_mutex_t lock ;
78+ struct simple_linked_list * list ;
79+ struct display * display ;
80+
81+ struct video_rxtx * video_rxtx ;
82+ struct state_audio * audio ;
8683};
8784
85+ static void vidcap_ug_input_done (void * state );
86+
8887static void
89- ug_input_frame_arrived (void *state, struct video_frame *f ,
88+ ug_input_frame_arrived (void * state , struct video_frame * v ,
9089 struct audio_frame * a )
9190{
92- auto *s = (ug_input_state *) state;
91+ struct ug_input_state * s = state ;
9392 assert (s -> magic == MAGIC );
94- lock_guard<mutex> lk (s->lock );
95- if (s->frame_queue .size () < MAX_QUEUE_SIZE) {
96- s->frame_queue .push ({f, a});
93+ pthread_mutex_lock (& s -> lock );
94+ if (simple_linked_list_size (s -> list ) < MAX_QUEUE_SIZE ) {
95+ struct av_frame * avf = (struct av_frame * ) malloc (sizeof * avf );
96+ avf -> aframe = a ;
97+ avf -> vframe = v ;
98+ simple_linked_list_append (s -> list , avf );
9799 } else {
98100 MSG (WARNING , "Dropping frame!\n" );
99101 AUDIO_FRAME_DISPOSE (a );
100- VIDEO_FRAME_DISPOSE (f );
102+ VIDEO_FRAME_DISPOSE (v );
101103 }
104+ pthread_mutex_unlock (& s -> lock );
102105}
103106
104107static void
@@ -123,9 +126,9 @@ parse_fmt(char *fmt, uint16_t *port, codec_t *decode_to)
123126 if (isdigit (tok [0 ])) {
124127 MSG (WARNING , "port specification without the keyword "
125128 "port= is deprecated\n" );
126- *port = stoi (tok);
129+ * port = atoi (tok );
127130 } else if (IS_KEY_PREFIX (tok , "port" )) {
128- *port = stoi (val);
131+ * port = atoi (val );
129132 } else if (IS_KEY_PREFIX (tok , "codec" )) {
130133 * decode_to = get_codec_from_name (val );
131134 if (* decode_to == VIDEO_CODEC_NONE ) {
@@ -156,7 +159,10 @@ static int vidcap_ug_input_init(const struct vidcap_params *cap_params, void **s
156159 return VIDCAP_INIT_FAIL ;
157160 }
158161
159- auto *s = new ug_input_state ();
162+ struct ug_input_state * s = calloc (1 , sizeof * s );
163+ s -> magic = MAGIC ;
164+ pthread_mutex_init (& s -> lock , nullptr );
165+ s -> list = simple_linked_list_init ();
160166
161167 char cfg [128 ] = "" ;
162168
@@ -192,10 +198,8 @@ static int vidcap_ug_input_init(const struct vidcap_params *cap_params, void **s
192198 // params["decoder_mode"].l = VIDEO_NORMAL;
193199 params .display_device = s -> display ;
194200
195- struct video_rxtx *rxtx = nullptr ;
196- int rc = vrxtx_init (" ultragrid_rtp" , ¶ms, &common, &rxtx);
201+ int rc = vrxtx_init ("ultragrid_rtp" , & params , & common , & s -> video_rxtx );
197202 assert (rc == 0 );
198- s->video_rxtx = unique_ptr<video_rxtx>(rxtx);
199203
200204 if (vidcap_params_get_flags (cap_params ) & VIDCAP_FLAG_AUDIO_ANY ) {
201205 struct audio_options opt = AUDIO_OPTIONS_INIT ;
@@ -205,10 +209,10 @@ static int vidcap_ug_input_init(const struct vidcap_params *cap_params, void **s
205209 opt .recv_cfg = "embedded" ;
206210 opt .proto = "ultragrid_rtp" ;
207211 opt .display = s -> display ;
208- opt.vrxtx = s->video_rxtx . get () ;
212+ opt .vrxtx = s -> video_rxtx ;
209213
210214 if (audio_init (& s -> audio , & opt , & common ) != 0 ) {
211- delete s ;
215+ vidcap_ug_input_done ( s ) ;
212216 return VIDCAP_INIT_FAIL ;
213217 }
214218
@@ -223,46 +227,55 @@ static int vidcap_ug_input_init(const struct vidcap_params *cap_params, void **s
223227
224228static void vidcap_ug_input_done (void * state )
225229{
226- auto s = ( ug_input_state *) state;
230+ struct ug_input_state * s = state ;
227231 assert (s -> magic == MAGIC );
228232
229233 audio_join (s -> audio );
230- s->video_rxtx -> join ( );
234+ vrxtx_join ( s -> video_rxtx );
231235
232236 // display_put_frame(s->display, nullptr, 0); // already done by ultragrid_rtp_video_rxtx::receiver_loop
233237 display_join (s -> display );
234238 display_done (s -> display );
235239
236- while (! s->frame_queue . empty () ) {
237- auto item = s->frame_queue . front ( );
238- s-> frame_queue . pop ( );
239- VIDEO_FRAME_DISPOSE (item. first );
240- AUDIO_FRAME_DISPOSE (item. second );
240+ while (simple_linked_list_size ( s -> list ) == 0 ) {
241+ struct av_frame * item = simple_linked_list_pop ( s -> list );
242+ VIDEO_FRAME_DISPOSE ( item -> vframe );
243+ AUDIO_FRAME_DISPOSE (item -> aframe );
244+ free (item );
241245 }
246+
242247 audio_done (s -> audio );
248+ vrxtx_destroy (s -> video_rxtx );
243249
244- delete s;
250+ pthread_mutex_destroy (& s -> lock );
251+ simple_linked_list_destroy (s -> list );
252+
253+ free (s );
245254}
246255
247256static struct video_frame * vidcap_ug_input_grab (void * state , struct audio_frame * * audio )
248257{
249- auto s = ( ug_input_state *) state;
258+ struct ug_input_state * s = state ;
250259 * audio = nullptr ;
251- lock_guard<mutex> lk (s->lock );
252- if (s->frame_queue .empty ()) {
260+ pthread_mutex_lock (& s -> lock );
261+ while (simple_linked_list_size (s -> list ) == 0 ) {
262+ pthread_mutex_unlock (& s -> lock );
253263 return nullptr ;
254264 }
255265
256- auto item = s->frame_queue . front ( );
257- struct video_frame *frame = item. first ;
258- *audio = item. second ;
259- s-> frame_queue . pop ( );
266+ struct av_frame * item = simple_linked_list_pop ( s -> list );
267+ struct video_frame * frame = item -> vframe ;
268+ * audio = item -> aframe ;
269+ free ( item );
260270 frame -> callbacks .dispose = vf_free ;
271+ pthread_mutex_unlock (& s -> lock );
261272
262273 return frame ;
263274}
264275
265- static void vidcap_ug_input_probe (device_info **available_cards, int *count, void (**deleter)(void *))
276+ static void
277+ vidcap_ug_input_probe (struct device_info * * available_cards , int * count ,
278+ void (* * deleter )(void * ))
266279{
267280 * deleter = free ;
268281 * count = 0 ;
0 commit comments