• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "config.h"
17 #include "gst_audio_capture_src.h"
18 #include <gst/gst.h>
19 #include <gst/audio/audio.h>
20 #include "media_errors.h"
21 #include "audio_capture_factory.h"
22 
23 static GstStaticPadTemplate gst_audio_capture_src_template =
24 GST_STATIC_PAD_TEMPLATE("src",
25     GST_PAD_SRC,
26     GST_PAD_ALWAYS,
27     GST_STATIC_CAPS("audio/x-raw, "
28         "format = (string) S16LE, "
29         "rate = (int) [ 1, MAX ], "
30         "layout = (string) interleaved, "
31         "channels = (int) [ 1, MAX ]"));
32 
33 enum {
34     PROP_0,
35     PROP_SOURCE_TYPE,
36     PROP_SAMPLE_RATE,
37     PROP_CHANNELS,
38     PROP_BITRATE,
39     PROP_TOKEN_ID,
40     PROP_FULL_TOKEN_ID,
41     PROP_APP_UID,
42     PROP_APP_PID,
43     PROP_BYPASS_AUDIO_SERVICE,
44     PROP_SUPPORTED_AUDIO_PARAMS
45 };
46 
47 using namespace OHOS::Media;
48 
49 #define gst_audio_capture_src_parent_class parent_class
50 G_DEFINE_TYPE(GstAudioCaptureSrc, gst_audio_capture_src, GST_TYPE_PUSH_SRC);
51 
52 static void gst_audio_capture_src_finalize(GObject *object);
53 static void gst_audio_capture_src_set_property(GObject *object, guint prop_id,
54     const GValue *value, GParamSpec *pspec);
55 static void gst_audio_capture_src_get_property(GObject *object, guint prop_id,
56     GValue *value, GParamSpec *pspec);
57 static GstFlowReturn gst_audio_capture_src_create(GstPushSrc *psrc, GstBuffer **outbuf);
58 static GstStateChangeReturn gst_audio_capture_src_change_state(GstElement *element, GstStateChange transition);
59 static gboolean gst_audio_capture_src_negotiate(GstBaseSrc *basesrc);
60 static void gst_audio_capture_src_getbuffer_timeout(GstPushSrc *psrc);
61 static void gst_audio_capture_src_mgr_init(GstAudioCaptureSrc *src);
62 static void gst_audio_capture_src_mgr_enable_watchdog(GstAudioCaptureSrc *src);
63 static void gst_audio_capture_src_mgr_disable_watchdog(GstAudioCaptureSrc *src);
64 
Alarm()65 void AudioManager::Alarm()
66 {
67     gst_audio_capture_src_getbuffer_timeout(&owner_);
68 }
69 
70 #define GST_TYPE_AUDIO_CAPTURE_SRC_SOURCE_TYPE (gst_audio_capture_src_source_type_get_type())
gst_audio_capture_src_source_type_get_type(void)71 static GType gst_audio_capture_src_source_type_get_type(void)
72 {
73     static GType audio_capture_src_source_type = 0;
74     static const GEnumValue source_types[] = {
75         {AUDIO_SOURCE_TYPE_DEFAULT, "MIC", "MIC"},
76         {AUDIO_SOURCE_TYPE_MIC, "MIC", "MIC"},
77         {0, nullptr, nullptr}
78     };
79     if (!audio_capture_src_source_type) {
80         audio_capture_src_source_type = g_enum_register_static("AudioSourceType", source_types);
81     }
82     return audio_capture_src_source_type;
83 }
84 
gst_audio_capture_src_class_init(GstAudioCaptureSrcClass * klass)85 static void gst_audio_capture_src_class_init(GstAudioCaptureSrcClass *klass)
86 {
87     GObjectClass *gobject_class = reinterpret_cast<GObjectClass *>(klass);
88     GstElementClass *gstelement_class = reinterpret_cast<GstElementClass *>(klass);
89     GstBaseSrcClass *gstbasesrc_class = reinterpret_cast<GstBaseSrcClass *>(klass);
90     GstPushSrcClass *gstpushsrc_class = reinterpret_cast<GstPushSrcClass *>(klass);
91     g_return_if_fail((gobject_class != nullptr) && (gstelement_class != nullptr) &&
92         (gstbasesrc_class != nullptr) && gstpushsrc_class != nullptr);
93 
94     gobject_class->finalize = gst_audio_capture_src_finalize;
95     gobject_class->set_property = gst_audio_capture_src_set_property;
96     gobject_class->get_property = gst_audio_capture_src_get_property;
97 
98     g_object_class_install_property(gobject_class, PROP_SOURCE_TYPE,
99         g_param_spec_enum("source-type", "Source type",
100             "Source type", GST_TYPE_AUDIO_CAPTURE_SRC_SOURCE_TYPE, AUDIO_SOURCE_TYPE_MIC,
101             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
102 
103     g_object_class_install_property(gobject_class, PROP_SAMPLE_RATE,
104         g_param_spec_uint("sample-rate", "Sample-Rate", "Audio sampling rate", 0, G_MAXINT32, 0,
105             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
106 
107     g_object_class_install_property(gobject_class, PROP_CHANNELS,
108         g_param_spec_uint("channels", "Channels", "Number of audio channels", 0, G_MAXINT32, 0,
109             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
110 
111     g_object_class_install_property(gobject_class, PROP_BITRATE,
112         g_param_spec_uint("bitrate", "Bitrate", "Audio bitrate", 0, G_MAXINT32, 0,
113             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
114 
115     g_object_class_install_property(gobject_class, PROP_TOKEN_ID,
116         g_param_spec_uint("token-id", "TokenID", "Token ID", 0, G_MAXUINT32, 0,
117             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
118 
119     g_object_class_install_property(gobject_class, PROP_FULL_TOKEN_ID,
120         g_param_spec_uint64("full-token-id", "FullTokenID", "Full Token ID", 0, G_MAXUINT64, 0,
121             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
122 
123     g_object_class_install_property(gobject_class, PROP_APP_UID,
124         g_param_spec_int("app-uid", "Appuid", "APP UID", 0, G_MAXINT32, 0,
125             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
126 
127     g_object_class_install_property(gobject_class, PROP_APP_PID,
128         g_param_spec_int("app-pid", "Apppid", "APP PID", 0, G_MAXINT32, 0,
129             (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
130 
131     g_object_class_install_property(gobject_class, PROP_BYPASS_AUDIO_SERVICE,
132         g_param_spec_boolean("bypass-audio-service", "Bypass Audio Service",
133             "do not enable audio service", FALSE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
134 
135     g_object_class_install_property(gobject_class, PROP_SUPPORTED_AUDIO_PARAMS,
136         g_param_spec_boolean("supported-audio-params", "issupport audio params",
137             "issupport audio params", FALSE, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
138 
139     gst_element_class_set_static_metadata(gstelement_class,
140         "Audio capture source", "Source/Audio",
141         "Retrieve audio frame from audio buffer queue", "OpenHarmony");
142 
143     gst_element_class_add_static_pad_template(gstelement_class, &gst_audio_capture_src_template);
144 
145     gstelement_class->change_state = gst_audio_capture_src_change_state;
146     gstbasesrc_class->negotiate = gst_audio_capture_src_negotiate;
147     gstpushsrc_class->create = gst_audio_capture_src_create;
148 }
149 
gst_audio_capture_src_init(GstAudioCaptureSrc * src)150 static void gst_audio_capture_src_init(GstAudioCaptureSrc *src)
151 {
152     g_return_if_fail(src != nullptr);
153     gst_base_src_set_format(GST_BASE_SRC(src), GST_FORMAT_TIME);
154     gst_base_src_set_live(GST_BASE_SRC(src), TRUE);
155     src->stream_type = AUDIO_STREAM_TYPE_UNKNOWN;
156     src->source_type = AUDIO_SOURCE_TYPE_MIC;
157     src->audio_capture = nullptr;
158     src->audio_mgr = nullptr;
159     src->src_caps = nullptr;
160     src->bitrate = 0;
161     src->channels = 0;
162     src->sample_rate = 0;
163     src->is_start = FALSE;
164     src->need_caps_info = TRUE;
165     src->token_id = 0;
166     src->full_token_id = 0;
167     src->appuid = 0;
168     src->apppid = 0;
169     src->bypass_audio = FALSE;
170     src->input_detection = TRUE;
171     gst_base_src_set_blocksize(GST_BASE_SRC(src), 0);
172 }
173 
gst_audio_capture_src_finalize(GObject * object)174 static void gst_audio_capture_src_finalize(GObject *object)
175 {
176     GST_DEBUG_OBJECT(object, "finalize");
177     GstAudioCaptureSrc *src = GST_AUDIO_CAPTURE_SRC(object);
178     g_return_if_fail(src != nullptr);
179     if (src->src_caps != nullptr) {
180         gst_caps_unref(src->src_caps);
181         src->src_caps = nullptr;
182     }
183 
184     if (src->audio_capture) {
185         src->audio_capture = nullptr;
186     }
187 
188     G_OBJECT_CLASS(parent_class)->finalize(object);
189 }
190 
gst_audio_capture_src_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)191 static void gst_audio_capture_src_set_property(GObject *object, guint prop_id,
192     const GValue *value, GParamSpec *pspec)
193 {
194     (void)pspec;
195     GstAudioCaptureSrc *src = GST_AUDIO_CAPTURE_SRC(object);
196     g_return_if_fail(src != nullptr);
197     switch (prop_id) {
198         case PROP_SOURCE_TYPE:
199             src->source_type = (AudioSourceType)g_value_get_enum(value);
200             break;
201         case PROP_SAMPLE_RATE:
202             src->sample_rate = g_value_get_uint(value);
203             break;
204         case PROP_CHANNELS:
205             src->channels = g_value_get_uint(value);
206             break;
207         case PROP_BITRATE:
208             src->bitrate = g_value_get_uint(value);
209             break;
210         case PROP_TOKEN_ID:
211             src->token_id = g_value_get_uint(value);
212             break;
213         case PROP_FULL_TOKEN_ID:
214             src->full_token_id = g_value_get_uint64(value);
215             break;
216         case PROP_APP_UID:
217             src->appuid = g_value_get_int(value);
218             break;
219         case PROP_APP_PID:
220             src->apppid = g_value_get_int(value);
221             break;
222         case PROP_BYPASS_AUDIO_SERVICE:
223             src->bypass_audio = g_value_get_boolean(value);
224             if (src->bypass_audio) {
225                 // Mutually exclusive protection is provided at the frame layer
226                 if (src->audio_capture) {
227                     src->audio_capture->WakeUpAudioThreads();
228                 }
229             }
230             break;
231         default:
232             break;
233     }
234 }
235 
gst_audio_capture_src_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)236 static void gst_audio_capture_src_get_property(GObject *object, guint prop_id,
237     GValue *value, GParamSpec *pspec)
238 {
239     (void)pspec;
240     GstAudioCaptureSrc *src = GST_AUDIO_CAPTURE_SRC(object);
241     g_return_if_fail(src != nullptr);
242     switch (prop_id) {
243         case PROP_SOURCE_TYPE:
244             g_value_set_enum(value, src->source_type);
245             break;
246         case PROP_SAMPLE_RATE:
247             g_value_set_uint(value, src->sample_rate);
248             break;
249         case PROP_CHANNELS:
250             g_value_set_uint(value, src->channels);
251             break;
252         case PROP_BITRATE:
253             g_value_set_uint(value, src->bitrate);
254             break;
255         case PROP_SUPPORTED_AUDIO_PARAMS:
256             if (src->audio_capture == nullptr) {
257                 src->audio_capture = OHOS::Media::AudioCaptureFactory::CreateAudioCapture(src->stream_type);
258                 g_return_if_fail(src->audio_capture != nullptr);
259             }
260             g_value_set_boolean(value, src->audio_capture->IsSupportedCaptureParameter(
261                 src->bitrate, src->channels, src->sample_rate));
262             break;
263         default:
264             break;
265     }
266 }
267 
process_caps_info(GstAudioCaptureSrc * src)268 static gboolean process_caps_info(GstAudioCaptureSrc *src)
269 {
270     guint bitrate = 0;
271     guint sample_rate = 0;
272     guint channels = 0;
273     g_return_val_if_fail(src != nullptr, FALSE);
274     g_return_val_if_fail(src->audio_capture->GetCaptureParameter(bitrate, channels, sample_rate) == MSERR_OK, FALSE);
275 
276     gboolean is_valid_params = TRUE;
277     guint64 channel_mask = 0;
278     switch (channels) {
279         case 1: {
280             GstAudioChannelPosition positions[1] = {GST_AUDIO_CHANNEL_POSITION_MONO};
281             if (!gst_audio_channel_positions_to_mask(positions, channels, FALSE, &channel_mask)) {
282                 GST_ERROR_OBJECT(src, "invalid channel positions");
283                 is_valid_params = FALSE;
284             }
285             break;
286         }
287         case 2: { // 2 channels
288             GstAudioChannelPosition positions[2] = {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
289                                                     GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT};
290             if (!gst_audio_channel_positions_to_mask(positions, channels, FALSE, &channel_mask)) {
291                 GST_ERROR_OBJECT(src, "invalid channel positions");
292                 is_valid_params = FALSE;
293             }
294             break;
295         }
296         default: {
297             is_valid_params = FALSE;
298             GST_ERROR_OBJECT(src, "invalid channels %u", channels);
299             break;
300         }
301     }
302     g_return_val_if_fail(is_valid_params == TRUE, FALSE);
303     if (src->src_caps != nullptr) {
304         gst_caps_unref(src->src_caps);
305     }
306     src->src_caps = gst_caps_new_simple("audio/x-raw",
307                                         "rate", G_TYPE_INT, sample_rate,
308                                         "channels", G_TYPE_INT, channels,
309                                         "format", G_TYPE_STRING, "S16LE",
310                                         "channel-mask", GST_TYPE_BITMASK, channel_mask,
311                                         "layout", G_TYPE_STRING, "interleaved", nullptr);
312     GstBaseSrc *basesrc = GST_BASE_SRC_CAST(src);
313     basesrc->segment.start = 0;
314     return TRUE;
315 }
316 
gst_state_change_ready_to_paused(GstAudioCaptureSrc * src)317 static GstStateChangeReturn gst_state_change_ready_to_paused(GstAudioCaptureSrc *src)
318 {
319     g_return_val_if_fail(src != nullptr, GST_STATE_CHANGE_FAILURE);
320     CHECK_AND_BREAK_REP_ERR(src->audio_capture != nullptr, src, "audio_capture is nullptr");
321     AudioCapture::AppInfo appInfo = {};
322     appInfo.appUid = src->appuid;
323     appInfo.appPid = src->apppid;
324     appInfo.appTokenId = src->token_id;
325     appInfo.appFullTokenId = src->full_token_id;
326     if (src->audio_capture->SetCaptureParameter(src->bitrate, src->channels, src->sample_rate, appInfo) != MSERR_OK) {
327         GST_ELEMENT_ERROR (src, CORE, STATE_CHANGE, ("SetCaptureParameter failed"),
328             ("SetCaptureParameter failed"));
329         return GST_STATE_CHANGE_FAILURE;
330     }
331     return GST_STATE_CHANGE_SUCCESS;
332 }
333 
gst_state_change_forward_direction(GstAudioCaptureSrc * src,GstStateChange transition)334 static GstStateChangeReturn gst_state_change_forward_direction(GstAudioCaptureSrc *src, GstStateChange transition)
335 {
336     g_return_val_if_fail(src != nullptr, GST_STATE_CHANGE_FAILURE);
337     switch (transition) {
338         case GST_STATE_CHANGE_NULL_TO_READY: {
339             if (src->audio_capture == nullptr) {
340                 src->audio_capture = OHOS::Media::AudioCaptureFactory::CreateAudioCapture(src->stream_type);
341                 CHECK_AND_BREAK_REP_ERR(src->audio_capture != nullptr, src, "failed to CreateAudioCapture");
342             }
343             break;
344         }
345         case GST_STATE_CHANGE_READY_TO_PAUSED: {
346             return gst_state_change_ready_to_paused(src);
347         }
348         case GST_STATE_CHANGE_PAUSED_TO_PLAYING: {
349             CHECK_AND_BREAK_REP_ERR(src->audio_capture != nullptr, src, "audio_capture is nullptr");
350             if (src->need_caps_info) {
351                 CHECK_AND_BREAK_REP_ERR(process_caps_info(src) == TRUE, src, "process caps info failed");
352                 src->need_caps_info = FALSE;
353             }
354             if (src->is_start == FALSE) {
355                 CHECK_AND_BREAK_REP_ERR(src->audio_capture->StartAudioCapture() == MSERR_OK,
356                     src, "StartAudioCapture failed");
357                 gst_audio_capture_src_mgr_init(src);
358                 src->is_start = TRUE;
359             } else {
360                 if (!src->bypass_audio) {
361                     CHECK_AND_BREAK_REP_ERR(src->audio_capture->ResumeAudioCapture() == MSERR_OK,
362                         src, "ResumeAudioCapture failed");
363                     gst_audio_capture_src_mgr_enable_watchdog(src);
364                 } else {
365                     src->audio_mgr = nullptr;
366                     CHECK_AND_BREAK_REP_ERR(src->audio_capture->WakeUpAudioThreads() == MSERR_OK,
367                         src, "WakeUpAudioThreads failed");
368                 }
369             }
370             break;
371         }
372         default:
373             break;
374     }
375     return GST_STATE_CHANGE_SUCCESS;
376 }
377 
gst_audio_capture_src_change_state(GstElement * element,GstStateChange transition)378 static GstStateChangeReturn gst_audio_capture_src_change_state(GstElement *element, GstStateChange transition)
379 {
380     g_return_val_if_fail(element != nullptr, GST_STATE_CHANGE_FAILURE);
381     GstAudioCaptureSrc *src = GST_AUDIO_CAPTURE_SRC(element);
382 
383     GstStateChangeReturn ret = gst_state_change_forward_direction(src, transition);
384     g_return_val_if_fail(ret == GST_STATE_CHANGE_SUCCESS, GST_STATE_CHANGE_FAILURE);
385 
386     ret = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition);
387 
388     switch (transition) {
389         case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
390             gst_audio_capture_src_mgr_disable_watchdog(src);
391             CHECK_AND_BREAK_REP_ERR(src->audio_capture != nullptr, src, "audio_capture is nullptr");
392             if (!src->bypass_audio) {
393                 CHECK_AND_BREAK_REP_ERR(src->audio_capture->PauseAudioCapture() == MSERR_OK,
394                     src, "PauseAudioCapture failed");
395             }
396             break;
397         case GST_STATE_CHANGE_PAUSED_TO_READY:
398             src->is_start = FALSE;
399             CHECK_AND_BREAK_REP_ERR(src->audio_capture != nullptr, src, "audio_capture is nullptr");
400             src->audio_mgr = nullptr;
401             CHECK_AND_BREAK_REP_ERR(src->audio_capture->StopAudioCapture() == MSERR_OK, src,
402                 "StopAudioCapture failed");
403             break;
404         case GST_STATE_CHANGE_READY_TO_NULL:
405             src->audio_capture = nullptr;
406             break;
407         default:
408             break;
409     }
410     return ret;
411 }
412 
gst_audio_capture_src_create(GstPushSrc * psrc,GstBuffer ** outbuf)413 static GstFlowReturn gst_audio_capture_src_create(GstPushSrc *psrc, GstBuffer **outbuf)
414 {
415     g_return_val_if_fail((psrc != nullptr) && (outbuf != nullptr), GST_FLOW_ERROR);
416     GstAudioCaptureSrc *src = GST_AUDIO_CAPTURE_SRC(psrc);
417     g_return_val_if_fail(src != nullptr, GST_FLOW_ERROR);
418     if (src->is_start == FALSE) {
419         return GST_FLOW_EOS;
420     }
421     g_return_val_if_fail(src->audio_capture != nullptr, GST_FLOW_ERROR);
422 
423     if (src->input_detection && src->audio_mgr != nullptr) {
424         src->audio_mgr->ResumeWatchDog();
425     }
426     std::shared_ptr<AudioBuffer> audio_buffer = src->audio_capture->GetBuffer();
427     if (src->input_detection && src->audio_mgr != nullptr) {
428         src->audio_mgr->PauseWatchDog();
429     }
430     if (audio_buffer == nullptr) {
431         if ((!src->bypass_audio) && src->is_start) {
432             GST_ELEMENT_ERROR (src, STREAM, FAILED, ("Input stream error, return null."),
433                 ("Input stream error, return null."));
434         }
435         return GST_FLOW_ERROR;
436     }
437     gst_base_src_set_blocksize(GST_BASE_SRC_CAST(src), audio_buffer->dataLen);
438 
439     *outbuf = audio_buffer->gstBuffer;
440     GST_BUFFER_DURATION(*outbuf) = audio_buffer->duration;
441     GST_BUFFER_TIMESTAMP(*outbuf) = audio_buffer->timestamp;
442     return GST_FLOW_OK;
443 }
444 
gst_audio_capture_src_negotiate(GstBaseSrc * basesrc)445 static gboolean gst_audio_capture_src_negotiate(GstBaseSrc *basesrc)
446 {
447     g_return_val_if_fail(basesrc != nullptr, false);
448     GstAudioCaptureSrc *src = GST_AUDIO_CAPTURE_SRC(basesrc);
449     g_return_val_if_fail(src != nullptr, FALSE);
450     (void)gst_base_src_wait_playing(basesrc);
451     g_return_val_if_fail(src->src_caps != nullptr, FALSE);
452     return gst_base_src_set_caps(basesrc, src->src_caps);
453 }
454 
gst_audio_capture_src_mgr_init(GstAudioCaptureSrc * src)455 static void gst_audio_capture_src_mgr_init(GstAudioCaptureSrc *src)
456 {
457     g_return_if_fail(src != nullptr);
458     if (src->input_detection && src->audio_mgr == nullptr) {
459         const guint32 timeoutMs = 3000; // Error will be reported if there is no data input in 3000ms by default.
460         GstPushSrc *psrc = GST_PUSH_SRC(src);
461         src->audio_mgr = std::make_shared<AudioManager>(*psrc, timeoutMs);
462         g_return_if_fail(src->audio_mgr != nullptr);
463     }
464 }
465 
gst_audio_capture_src_mgr_enable_watchdog(GstAudioCaptureSrc * src)466 static void gst_audio_capture_src_mgr_enable_watchdog(GstAudioCaptureSrc *src)
467 {
468     g_return_if_fail(src != nullptr);
469     if (src->input_detection && src->audio_mgr != nullptr) {
470         src->audio_mgr->EnableWatchDog();
471         src->audio_mgr->PauseWatchDog();
472     }
473 }
474 
gst_audio_capture_src_mgr_disable_watchdog(GstAudioCaptureSrc * src)475 static void gst_audio_capture_src_mgr_disable_watchdog(GstAudioCaptureSrc *src)
476 {
477     g_return_if_fail(src != nullptr);
478     if (src->audio_mgr != nullptr) {
479         src->audio_mgr->DisableWatchDog();
480     }
481 }
482 
gst_audio_capture_src_getbuffer_timeout(GstPushSrc * psrc)483 static void gst_audio_capture_src_getbuffer_timeout(GstPushSrc *psrc)
484 {
485     g_return_if_fail(psrc != nullptr);
486     GstAudioCaptureSrc *src = GST_AUDIO_CAPTURE_SRC(psrc);
487     g_return_if_fail(src != nullptr);
488 
489     GST_ELEMENT_ERROR (src, RESOURCE, READ,
490         ("Audio input stream timeout, please confirm whether the input is normal."),
491         ("Audio input stream timeout, please confirm whether the input is normal."));
492 }
493 
plugin_init(GstPlugin * plugin)494 static gboolean plugin_init(GstPlugin *plugin)
495 {
496     g_return_val_if_fail(plugin != nullptr, false);
497     return gst_element_register(plugin, "audiocapturesrc", GST_RANK_PRIMARY, GST_TYPE_AUDIO_CAPTURE_SRC);
498 }
499 
500 GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
501     GST_VERSION_MINOR,
502     _audio_capture_src,
503     "GStreamer Audio Capture Source",
504     plugin_init,
505     PACKAGE_VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
506