Fix memory leak in MediaFoundation
Fix SDP renegotiation issue Fix deadlock in BFCP video producer (when stopped while encoding)
This commit is contained in:
parent
a28212a852
commit
5f80c12eed
|
@ -575,11 +575,9 @@ static int _plugin_win_mf_producer_video_unprepare(plugin_win_mf_producer_video_
|
|||
}
|
||||
if(pSelf->pSource){
|
||||
pSelf->pSource->Shutdown();
|
||||
pSelf->pSource = NULL;
|
||||
}
|
||||
if(pSelf->pSession){
|
||||
pSelf->pSession->Shutdown();
|
||||
pSelf->pSession = NULL;
|
||||
}
|
||||
|
||||
SafeRelease(&pSelf->pEncoder);
|
||||
|
|
|
@ -51,6 +51,7 @@ typedef struct tdav_session_video_s
|
|||
tsk_bool_t jb_enabled;
|
||||
tsk_bool_t zero_artifacts;
|
||||
tsk_bool_t fps_changed;
|
||||
tsk_bool_t started;
|
||||
|
||||
struct{
|
||||
const void* context;
|
||||
|
|
|
@ -274,13 +274,13 @@ static int _tdav_producer_screencast_grab(tdav_producer_screencast_gdi_t* p_self
|
|||
|
||||
hSrcDC = GetDC(p_self->hwnd_src);
|
||||
if (!hSrcDC) {
|
||||
TSK_DEBUG_ERROR("GetDC(%llu) failed", *((uint64_t*)p_self->hwnd_src));
|
||||
TSK_DEBUG_ERROR("GetDC(%x) failed", p_self->hwnd_src);
|
||||
ret = -5;
|
||||
goto bail;
|
||||
}
|
||||
hMemDC = CreateCompatibleDC(hSrcDC);
|
||||
if (!hMemDC) {
|
||||
TSK_DEBUG_ERROR("CreateCompatibleDC(%llu) failed", *((uint64_t*)hSrcDC));
|
||||
TSK_DEBUG_ERROR("CreateCompatibleDC(%x) failed", hSrcDC);
|
||||
ret = -6;
|
||||
goto bail;
|
||||
}
|
||||
|
@ -374,7 +374,7 @@ static int _tdav_producer_screencast_grab(tdav_producer_screencast_gdi_t* p_self
|
|||
}
|
||||
}
|
||||
|
||||
// encode and send
|
||||
// encode and send data
|
||||
TMEDIA_PRODUCER(p_self)->enc_cb.callback(TMEDIA_PRODUCER(p_self)->enc_cb.callback_data, p_self->p_buff_neg, p_self->bitmapInfoNeg.bmiHeader.biSizeImage);
|
||||
|
||||
bail:
|
||||
|
|
|
@ -347,7 +347,13 @@ static int tdav_session_video_producer_enc_cb(const void* callback_data, const v
|
|||
|
||||
// do nothing if session is held
|
||||
// when the session is held the end user will get feedback he also has possibilities to put the consumer and producer on pause
|
||||
if(TMEDIA_SESSION(base)->lo_held){
|
||||
if (TMEDIA_SESSION(base)->lo_held) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// do nothing if not started yet
|
||||
if (!video->started) {
|
||||
TSK_DEBUG_INFO("Video session not started yet");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1053,7 +1059,7 @@ static int tdav_session_video_start(tmedia_session_t* self)
|
|||
tdav_session_av_t* base;
|
||||
tmedia_param_t* media_param;
|
||||
|
||||
if(!self){
|
||||
if (!self) {
|
||||
TSK_DEBUG_ERROR("Invalid parameter");
|
||||
return -1;
|
||||
}
|
||||
|
@ -1062,7 +1068,7 @@ static int tdav_session_video_start(tmedia_session_t* self)
|
|||
base = (tdav_session_av_t*)self;
|
||||
|
||||
// ENCODER codec
|
||||
if(!(codec = tdav_session_av_get_best_neg_codec(base))){
|
||||
if (!(codec = tdav_session_av_get_best_neg_codec(base))) {
|
||||
TSK_DEBUG_ERROR("No codec matched");
|
||||
return -2;
|
||||
}
|
||||
|
@ -1083,18 +1089,18 @@ static int tdav_session_video_start(tmedia_session_t* self)
|
|||
}
|
||||
tsk_mutex_unlock(video->encoder.h_mutex);
|
||||
|
||||
if(video->jb){
|
||||
if((ret = tdav_video_jb_start(video->jb))){
|
||||
if (video->jb) {
|
||||
if ((ret = tdav_video_jb_start(video->jb))) {
|
||||
TSK_DEBUG_ERROR("Failed to start jitter buffer");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if((ret = tdav_session_av_start(base, video->encoder.codec))){
|
||||
if ((ret = tdav_session_av_start(base, video->encoder.codec))) {
|
||||
TSK_DEBUG_ERROR("tdav_session_av_start(video) failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
video->started = tsk_true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1108,8 +1114,11 @@ static int tdav_session_video_stop(tmedia_session_t* self)
|
|||
|
||||
video = (tdav_session_video_t*)self;
|
||||
base = (tdav_session_av_t*)self;
|
||||
|
||||
// must be here to make sure not other thread will lock the encoder once we have done it
|
||||
video->started = tsk_false;
|
||||
|
||||
if(video->jb){
|
||||
if (video->jb) {
|
||||
ret = tdav_video_jb_stop(video->jb);
|
||||
}
|
||||
// clear AVPF packets and wait for the dtor() before destroying the list
|
||||
|
|
|
@ -53,7 +53,9 @@ const tmedia_session_plugin_def_t* __tmedia_session_plugins[TMED_SESSION_MAX_PLU
|
|||
/* === local functions === */
|
||||
static int _tmedia_session_mgr_recv_rtcp_event(tmedia_session_mgr_t* self, tmedia_type_t media_type, tmedia_rtcp_event_type_t event_type, uint32_t ssrc_media, uint64_t session_id);
|
||||
static int _tmedia_session_mgr_load_sessions(tmedia_session_mgr_t* self);
|
||||
static int _tmedia_session_mgr_disable_session_with_type(tmedia_session_mgr_t* self, tmedia_type_t media_type);
|
||||
static int _tmedia_session_mgr_disable_or_enable_session_with_type(tmedia_session_mgr_t* self, tmedia_type_t media_type, tsk_bool_t enable);
|
||||
#define _tmedia_session_mgr_disable_session_with_type(self, media_type) _tmedia_session_mgr_disable_or_enable_session_with_type((self), (media_type), tsk_false)
|
||||
#define _tmedia_session_mgr_enable_session_with_type(self, media_type) _tmedia_session_mgr_disable_or_enable_session_with_type((self), (media_type), tsk_true)
|
||||
static const tmedia_session_t* _tmedia_session_mgr_find_session_at_index(const tmedia_sessions_L_t* list, tsk_size_t index);
|
||||
static int _tmedia_session_mgr_clear_sessions(tmedia_session_mgr_t* self);
|
||||
static int _tmedia_session_mgr_apply_params(tmedia_session_mgr_t* self);
|
||||
|
@ -1988,23 +1990,32 @@ static int _tmedia_session_mgr_load_sessions(tmedia_session_mgr_t* self)
|
|||
//while (tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &__none_media_type)) ;
|
||||
/* for each registered plugin create a session instance */
|
||||
while ((i < TMED_SESSION_MAX_PLUGINS) && (plugin = __tmedia_session_plugins[i++])) {
|
||||
if ((plugin->type & self->type) == plugin->type && !has_media(plugin->type)) {// we don't have a session with this media type yet
|
||||
if ((session = tmedia_session_create(plugin->type))) {
|
||||
/* do not call "tmedia_session_mgr_set()" here to avoid applying parms before the creation of all session */
|
||||
if ((plugin->type & self->type) == plugin->type) { /* media_type *IS* enabled */
|
||||
if (has_media(plugin->type)) {
|
||||
// we already have a matching media session -> enable it if not already done
|
||||
_tmedia_session_mgr_enable_session_with_type(self, plugin->type);
|
||||
}
|
||||
else {
|
||||
// we don't have a matching media session yet
|
||||
if ((session = tmedia_session_create(plugin->type))) {
|
||||
/* do not call "tmedia_session_mgr_set()" here to avoid applying parms before the creation of all session */
|
||||
|
||||
/* set other default values */
|
||||
/* set other default values */
|
||||
|
||||
// set callback functions
|
||||
tmedia_session_set_onerror_cbfn(session, self->onerror_cb.usrdata, self->onerror_cb.fun);
|
||||
|
||||
/* push session */
|
||||
tsk_list_push_back_data(self->sessions, (void**)(&session));
|
||||
// set callback functions
|
||||
tmedia_session_set_onerror_cbfn(session, self->onerror_cb.usrdata, self->onerror_cb.fun);
|
||||
|
||||
/* push session */
|
||||
tsk_list_push_back_data(self->sessions, (void**)(&session));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(plugin->type & self->type) && has_media(plugin->type)) { // we have media session from previous call (before update)
|
||||
// do not remove to make sure media indexes match -> see rfc 3264 section 8
|
||||
// tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &(plugin->type));
|
||||
_tmedia_session_mgr_disable_session_with_type(self, plugin->type);
|
||||
else { /* media_type *IS NOT* enabled */
|
||||
if (has_media(plugin->type)) {
|
||||
// do not remove to make sure media indexes match -> see rfc 3264 section 8
|
||||
// tsk_list_remove_item_by_pred(self->sessions, __pred_find_session_by_type, &(plugin->type));
|
||||
_tmedia_session_mgr_disable_session_with_type(self, plugin->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* set default values and apply params*/
|
||||
|
@ -2037,7 +2048,7 @@ static const tmedia_session_t* _tmedia_session_mgr_find_session_at_index(const t
|
|||
}
|
||||
|
||||
/* internal function */
|
||||
static int _tmedia_session_mgr_disable_session_with_type(tmedia_session_mgr_t* self, tmedia_type_t media_type)
|
||||
static int _tmedia_session_mgr_disable_or_enable_session_with_type(tmedia_session_mgr_t* self, tmedia_type_t media_type, tsk_bool_t enable)
|
||||
{
|
||||
tsk_list_item_t *item;
|
||||
tmedia_session_t *session;
|
||||
|
@ -2045,13 +2056,22 @@ static int _tmedia_session_mgr_disable_session_with_type(tmedia_session_mgr_t* s
|
|||
|
||||
tsk_list_foreach(item, self->sessions) {
|
||||
if ((session = (tmedia_session_t*)item->data) && session->plugin && session->plugin->type == media_type) {
|
||||
if (session->plugin->stop) {
|
||||
session->plugin->stop(session);
|
||||
if (enable) {
|
||||
if (session->M.lo && !session->M.lo->port) {
|
||||
TSK_OBJECT_SAFE_FREE(session->M.ro);
|
||||
TSK_OBJECT_SAFE_FREE(session->M.lo);
|
||||
session->prepared = tsk_false;
|
||||
}
|
||||
}
|
||||
if (session->M.lo) {
|
||||
session->M.lo->port = 0;
|
||||
else {
|
||||
if (session->plugin->stop) {
|
||||
session->plugin->stop(session);
|
||||
}
|
||||
if (session->M.lo) {
|
||||
session->M.lo->port = 0;
|
||||
}
|
||||
session->prepared = tsk_false;
|
||||
}
|
||||
session->prepared = tsk_false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue