From: Sangchul Lee Date: Fri, 2 Jul 2021 03:27:09 +0000 (+0900) Subject: Add new group - CAPI_MEDIA_WEBRTC_MEDIA_RENDER_MODULE X-Git-Tag: submit/tizen/20210729.023123~29 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=238540b74517f08f9e39fce5832d1c3a3465d2cf;p=platform%2Fcore%2Fapi%2Fwebrtc.git Add new group - CAPI_MEDIA_WEBRTC_MEDIA_RENDER_MODULE Functions below are included in this group. - webrtc_set_sound_stream_info() - webrtc_set_display() - webrtc_set_encoded_audio_frame_cb() - webrtc_unset_encoded_audio_frame_cb() - webrtc_set_encoded_video_frame_cb() - webrtc_unset_encoded_video_frame_cb() [Version] 0.2.31 [Issue Type] Doxygen Change-Id: I70900fa9ab4ded21f5283f611b8e4dddca6b9442 Signed-off-by: Sangchul Lee --- diff --git a/include/webrtc.h b/include/webrtc.h index 4f3acb4b..a8f925c7 100644 --- a/include/webrtc.h +++ b/include/webrtc.h @@ -47,12 +47,6 @@ extern "C" { */ typedef void *webrtc_h; -/** - * @brief WebRTC display handle type. - * @since_tizen 6.5 - */ -typedef void *webrtc_display_h; - /** * @brief Enumeration for WebRTC error. * @since_tizen 6.5 @@ -190,6 +184,21 @@ typedef enum { WEBRTC_TRANSCEIVER_DIRECTION_SENDRECV, /**< Send and receive */ } webrtc_transceiver_direction_e; +/** + * @} + */ + +/** +* @addtogroup CAPI_MEDIA_WEBRTC_MEDIA_RENDER_MODULE +* @{ +*/ + +/** + * @brief WebRTC display handle type. + * @since_tizen 6.5 + */ +typedef void *webrtc_display_h; + /** * @} */ @@ -356,25 +365,6 @@ typedef void (*webrtc_ice_candidate_cb)(webrtc_h webrtc, const char *candidate, */ typedef void (*webrtc_track_added_cb)(webrtc_h webrtc, webrtc_media_type_e type, unsigned int track_id, void *user_data); -/** - * @brief Called when each audio or video frame is ready to render via the WebRTC pipeline after the negotiation. - * @since_tizen 6.5 - * @remarks The @a webrtc is the same object for which the callback was set.\nThe @a webrtc should not be released.\n - * Use media_packet_get_buffer_data_ptr() with @a packet to get the Gstreamer buffer pointer. - * The @a packet should be released by calling media_packet_destroy() after use. - * @param[in] webrtc WebRTC handle - * @param[in] type The media type - * @param[in] track_id The track id - * @param[in] packet The media packet which has a frame data - * @param[in] user_data The user data passed from the callback registration function - * @see webrtc_set_encoded_audio_frame_cb() - * @see webrtc_unset_encoded_audio_frame_cb() - * @see webrtc_set_encoded_video_frame_cb() - * @see webrtc_unset_encoded_video_frame_cb() - * @see media_packet_get_buffer_data_ptr() - */ -typedef void (*webrtc_encoded_frame_cb)(webrtc_h webrtc, webrtc_media_type_e type, unsigned int track_id, media_packet_h packet, void *user_data); - /** * @} */ @@ -395,6 +385,34 @@ typedef void (*webrtc_encoded_frame_cb)(webrtc_h webrtc, webrtc_media_type_e typ */ typedef void (*webrtc_media_packet_source_buffer_state_changed_cb)(unsigned int source_id, webrtc_media_packet_source_buffer_state_e state, void *user_data); +/** + * @} + */ + +/** +* @addtogroup CAPI_MEDIA_WEBRTC_MEDIA_RENDER_MODULE +* @{ +*/ + +/** + * @brief Called when each audio or video frame is ready to be rendered via the WebRTC pipeline after the negotiation. + * @since_tizen 6.5 + * @remarks The @a webrtc is the same object for which the callback was set.\nThe @a webrtc should not be released.\n + * Use media_packet_get_buffer_data_ptr() with @a packet to get the Gstreamer buffer pointer.\n + * The @a packet should be released using media_packet_destroy(). + * @param[in] webrtc WebRTC handle + * @param[in] type The media type + * @param[in] track_id The track id + * @param[in] packet The media packet which has a frame data + * @param[in] user_data The user data passed from the callback registration function + * @see webrtc_set_encoded_audio_frame_cb() + * @see webrtc_unset_encoded_audio_frame_cb() + * @see webrtc_set_encoded_video_frame_cb() + * @see webrtc_unset_encoded_video_frame_cb() + * @see media_packet_get_buffer_data_ptr() + */ +typedef void (*webrtc_encoded_frame_cb)(webrtc_h webrtc, webrtc_media_type_e type, unsigned int track_id, media_packet_h packet, void *user_data); + /** * @} */ @@ -953,12 +971,12 @@ int webrtc_media_packet_source_push_packet(webrtc_h webrtc, unsigned int source_ */ /** -* @addtogroup CAPI_MEDIA_WEBRTC_MODULE +* @addtogroup CAPI_MEDIA_WEBRTC_MEDIA_RENDER_MODULE * @{ */ /** - * @brief Sets a sound manager stream information to the audio track. + * @brief Sets a sound manager stream information to the audio track to be rendered. * @since_tizen 6.5 * @remarks Call this function within webrtc_track_added_cb(), otherwise #WEBRTC_ERROR_INVALID_OPERATION will be returned.\n * If webrtc_set_encoded_audio_frame_cb() has been called, it will return #WEBRTC_ERROR_INVALID_OPERATION.\n @@ -981,7 +999,7 @@ int webrtc_media_packet_source_push_packet(webrtc_h webrtc, unsigned int source_ int webrtc_set_sound_stream_info(webrtc_h webrtc, unsigned int track_id, sound_stream_info_h stream_info); /** - * @brief Sets a display to the video track. + * @brief Sets a display to the video track to be rendered. * @since_tizen 6.5 * @remarks Call this function within webrtc_track_added_cb(), otherwise #WEBRTC_ERROR_INVALID_OPERATION will be returned.\n * If webrtc_set_encoded_video_frame_cb() has been called, it will return #WEBRTC_ERROR_INVALID_OPERATION. @@ -1000,6 +1018,85 @@ int webrtc_set_sound_stream_info(webrtc_h webrtc, unsigned int track_id, sound_s */ int webrtc_set_display(webrtc_h webrtc, unsigned int track_id, webrtc_display_type_e type, webrtc_display_h display); +/** + * @brief Sets an encoded audio frame callback function to be invoked when each audio frame is ready to be rendered. + * @since_tizen 6.5 + * @remarks If @a callback is set, audio data from the remote peer will be forwarded to @a callback without being rendered by itself.\n + * The registered callback will be invoked in an internal thread of the webrtc. + * @param[in] webrtc WebRTC handle + * @param[in] callback Callback function pointer + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state + * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. + * @post webrtc_encoded_frame_cb() will be invoked. + * @see webrtc_unset_encoded_audio_frame_cb() + * @see webrtc_encoded_frame_cb() + */ +int webrtc_set_encoded_audio_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data); + +/** + * @brief Unsets the encoded audio frame callback function. + * @since_tizen 6.5 + * @param[in] webrtc WebRTC handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation + * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state + * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. + * @see webrtc_set_encoded_audio_frame_cb() + */ +int webrtc_unset_encoded_audio_frame_cb(webrtc_h webrtc); + +/** + * @brief Sets an encoded video frame callback function to be invoked when each video frame is ready to be rendered. + * @since_tizen 6.5 + * @remarks If @a callback is set, video data from the remote peer will be forwarded to @a callback without being rendered by itself.\n + * The registered callback will be invoked in an internal thread of the webrtc. + * @param[in] webrtc WebRTC handle + * @param[in] callback Callback function pointer + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state + * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. + * @post webrtc_encoded_frame_cb() will be invoked. + * @see webrtc_unset_encoded_video_frame_cb() + * @see webrtc_encoded_frame_cb() + */ +int webrtc_set_encoded_video_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data); + +/** + * @brief Unsets the encoded video frame callback function. + * @since_tizen 6.5 + * @param[in] webrtc WebRTC handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #WEBRTC_ERROR_NONE Successful + * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation + * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state + * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. + * @see webrtc_set_encoded_video_frame_cb() + */ +int webrtc_unset_encoded_video_frame_cb(webrtc_h webrtc); + +/** + * @} + */ + +/** +* @addtogroup CAPI_MEDIA_WEBRTC_MODULE +* @{ +*/ + /** * @brief Sets a STUN server URL. * @since_tizen 6.5 @@ -1443,74 +1540,6 @@ int webrtc_set_track_added_cb(webrtc_h webrtc, webrtc_track_added_cb callback, v */ int webrtc_unset_track_added_cb(webrtc_h webrtc); -/** - * @brief Sets an encoded audio frame callback function to be invoked when each audio frame is ready to render. - * @since_tizen 6.5 - * @remarks If @a callback is set, audio data from the remote peer will be forwarded to @a callback without rendering it by itself. - * @param[in] webrtc WebRTC handle - * @param[in] callback Callback function pointer - * @param[in] user_data The user data to be passed to the callback function - * @return @c 0 on success, - * otherwise a negative error value - * @retval #WEBRTC_ERROR_NONE Successful - * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. - * @post webrtc_encoded_frame_cb() will be invoked. - * @see webrtc_unset_encoded_audio_frame_cb() - * @see webrtc_encoded_frame_cb() - */ -int webrtc_set_encoded_audio_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data); - -/** - * @brief Unsets the encoded audio frame callback function. - * @since_tizen 6.5 - * @param[in] webrtc WebRTC handle - * @return @c 0 on success, - * otherwise a negative error value - * @retval #WEBRTC_ERROR_NONE Successful - * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation - * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. - * @see webrtc_set_encoded_audio_frame_cb() - */ -int webrtc_unset_encoded_audio_frame_cb(webrtc_h webrtc); - -/** - * @brief Sets an encoded video frame callback function to be invoked when each video frame is ready to render. - * @since_tizen 6.5 - * @remarks If @a callback is set, video data from the remote peer will be forwarded to @a callback without rendering it by itself. - * @param[in] webrtc WebRTC handle - * @param[in] callback Callback function pointer - * @param[in] user_data The user data to be passed to the callback function - * @return @c 0 on success, - * otherwise a negative error value - * @retval #WEBRTC_ERROR_NONE Successful - * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. - * @post webrtc_encoded_frame_cb() will be invoked. - * @see webrtc_unset_encoded_video_frame_cb() - * @see webrtc_encoded_frame_cb() - */ -int webrtc_set_encoded_video_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data); - -/** - * @brief Unsets the encoded video frame callback function. - * @since_tizen 6.5 - * @param[in] webrtc WebRTC handle - * @return @c 0 on success, - * otherwise a negative error value - * @retval #WEBRTC_ERROR_NONE Successful - * @retval #WEBRTC_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #WEBRTC_ERROR_INVALID_OPERATION Invalid operation - * @retval #WEBRTC_ERROR_INVALID_STATE Invalid state - * @pre @a webrtc state must be set to #WEBRTC_STATE_IDLE or #WEBRTC_STATE_NEGOTIATING. - * @see webrtc_set_encoded_video_frame_cb() - */ -int webrtc_unset_encoded_video_frame_cb(webrtc_h webrtc); - /** * @} */ diff --git a/packaging/capi-media-webrtc.spec b/packaging/capi-media-webrtc.spec index 06ddbac1..527ce3ab 100644 --- a/packaging/capi-media-webrtc.spec +++ b/packaging/capi-media-webrtc.spec @@ -1,6 +1,6 @@ Name: capi-media-webrtc Summary: A WebRTC library in Tizen Native API -Version: 0.2.30 +Version: 0.2.31 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/webrtc.c b/src/webrtc.c index d8df02e9..22a91aed 100644 --- a/src/webrtc.c +++ b/src/webrtc.c @@ -643,6 +643,96 @@ int webrtc_set_display(webrtc_h webrtc, unsigned int track_id, webrtc_display_ty return ret; } +int webrtc_set_encoded_audio_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL"); + + g_mutex_lock(&_webrtc->mutex); + + RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); + + LOG_WARNING_IF_CALLBACK_EXISTS(_webrtc->encoded_audio_frame_cb); + + _webrtc->encoded_audio_frame_cb.callback = callback; + _webrtc->encoded_audio_frame_cb.user_data = user_data; + + LOG_INFO("callback[%p] user_data[%p]", callback, user_data); + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + +int webrtc_unset_encoded_audio_frame_cb(webrtc_h webrtc) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + + g_mutex_lock(&_webrtc->mutex); + + RET_VAL_WITH_UNLOCK_IF(_webrtc->encoded_audio_frame_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "callback was not set"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); + + LOG_INFO("callback[%p] user_data[%p] is reset to NULL", + _webrtc->encoded_audio_frame_cb.callback, _webrtc->encoded_audio_frame_cb.user_data); + + _webrtc->encoded_audio_frame_cb.callback = NULL; + _webrtc->encoded_audio_frame_cb.user_data = NULL; + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + +int webrtc_set_encoded_video_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL"); + + g_mutex_lock(&_webrtc->mutex); + + RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); + + LOG_WARNING_IF_CALLBACK_EXISTS(_webrtc->encoded_video_frame_cb); + + _webrtc->encoded_video_frame_cb.callback = callback; + _webrtc->encoded_video_frame_cb.user_data = user_data; + + LOG_INFO("callback[%p] user_data[%p]", callback, user_data); + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + +int webrtc_unset_encoded_video_frame_cb(webrtc_h webrtc) +{ + webrtc_s *_webrtc = (webrtc_s*)webrtc; + + RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); + + g_mutex_lock(&_webrtc->mutex); + + RET_VAL_WITH_UNLOCK_IF(_webrtc->encoded_video_frame_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "callback was not set"); + RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); + + LOG_INFO("callback[%p] user_data[%p] is reset to NULL", + _webrtc->encoded_video_frame_cb.callback, _webrtc->encoded_video_frame_cb.user_data); + + _webrtc->encoded_video_frame_cb.callback = NULL; + _webrtc->encoded_video_frame_cb.user_data = NULL; + + g_mutex_unlock(&_webrtc->mutex); + + return WEBRTC_ERROR_NONE; +} + int webrtc_set_stun_server(webrtc_h webrtc, const char *stun_server) { webrtc_s *_webrtc = (webrtc_s*)webrtc; @@ -1125,96 +1215,6 @@ int webrtc_unset_track_added_cb(webrtc_h webrtc) return WEBRTC_ERROR_NONE; } -int webrtc_set_encoded_audio_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data) -{ - webrtc_s *_webrtc = (webrtc_s*)webrtc; - - RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); - RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL"); - - g_mutex_lock(&_webrtc->mutex); - - RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); - - LOG_WARNING_IF_CALLBACK_EXISTS(_webrtc->encoded_audio_frame_cb); - - _webrtc->encoded_audio_frame_cb.callback = callback; - _webrtc->encoded_audio_frame_cb.user_data = user_data; - - LOG_INFO("callback[%p] user_data[%p]", callback, user_data); - - g_mutex_unlock(&_webrtc->mutex); - - return WEBRTC_ERROR_NONE; -} - -int webrtc_unset_encoded_audio_frame_cb(webrtc_h webrtc) -{ - webrtc_s *_webrtc = (webrtc_s*)webrtc; - - RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); - - g_mutex_lock(&_webrtc->mutex); - - RET_VAL_WITH_UNLOCK_IF(_webrtc->encoded_audio_frame_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "callback was not set"); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); - - LOG_INFO("callback[%p] user_data[%p] is reset to NULL", - _webrtc->encoded_audio_frame_cb.callback, _webrtc->encoded_audio_frame_cb.user_data); - - _webrtc->encoded_audio_frame_cb.callback = NULL; - _webrtc->encoded_audio_frame_cb.user_data = NULL; - - g_mutex_unlock(&_webrtc->mutex); - - return WEBRTC_ERROR_NONE; -} - -int webrtc_set_encoded_video_frame_cb(webrtc_h webrtc, webrtc_encoded_frame_cb callback, void *user_data) -{ - webrtc_s *_webrtc = (webrtc_s*)webrtc; - - RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); - RET_VAL_IF(callback == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "callback is NULL"); - - g_mutex_lock(&_webrtc->mutex); - - RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); - - LOG_WARNING_IF_CALLBACK_EXISTS(_webrtc->encoded_video_frame_cb); - - _webrtc->encoded_video_frame_cb.callback = callback; - _webrtc->encoded_video_frame_cb.user_data = user_data; - - LOG_INFO("callback[%p] user_data[%p]", callback, user_data); - - g_mutex_unlock(&_webrtc->mutex); - - return WEBRTC_ERROR_NONE; -} - -int webrtc_unset_encoded_video_frame_cb(webrtc_h webrtc) -{ - webrtc_s *_webrtc = (webrtc_s*)webrtc; - - RET_VAL_IF(_webrtc == NULL, WEBRTC_ERROR_INVALID_PARAMETER, "webrtc is NULL"); - - g_mutex_lock(&_webrtc->mutex); - - RET_VAL_WITH_UNLOCK_IF(_webrtc->encoded_video_frame_cb.callback == NULL, WEBRTC_ERROR_INVALID_OPERATION, &_webrtc->mutex, "callback was not set"); - RET_VAL_WITH_UNLOCK_IF(_webrtc->state == WEBRTC_STATE_PLAYING, WEBRTC_ERROR_INVALID_STATE, &_webrtc->mutex, "the state should NOT be PLAYING"); - - LOG_INFO("callback[%p] user_data[%p] is reset to NULL", - _webrtc->encoded_video_frame_cb.callback, _webrtc->encoded_video_frame_cb.user_data); - - _webrtc->encoded_video_frame_cb.callback = NULL; - _webrtc->encoded_video_frame_cb.user_data = NULL; - - g_mutex_unlock(&_webrtc->mutex); - - return WEBRTC_ERROR_NONE; -} - int webrtc_create_offer(webrtc_h webrtc, bundle *options, char **offer) { int ret = WEBRTC_ERROR_NONE;