<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Please see the comments in the following codes, at the moment, A & B both have one audio & video stream separately and B is starting to add an extra sharing video:</div><div><br></div><div>static int sdp_requires_deferral(struct ast_sip_session *session, const pjmedia_sdp_session *sdp)</div><div>{</div><div><span style="white-space:pre"> </span>int i;</div><div><br></div><div><span style="white-space:pre">       </span>if (!session->pending_media_state->topology) {</div><div><span style="white-space:pre">          </span>session->pending_media_state->topology = ast_stream_topology_alloc();</div><div><span style="white-space:pre">           </span>if (!session->pending_media_state->topology) {</div><div><span style="white-space:pre">                  </span>return -1;</div><div><span style="white-space:pre">            </span>}</div><div><span style="white-space:pre">     </span>}</div><div><br></div><div><span style="white-space:pre">    </span>for (i = 0; i < sdp->media_count; ++i) {</div><div><span style="white-space:pre">                </span>/* See if there are registered handlers for this media stream type */</div><div><span style="white-space:pre">         </span>char media[20];</div><div><span style="white-space:pre">               </span>struct ast_sip_session_sdp_handler *handler;</div><div><span style="white-space:pre">          </span>RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);</div><div><span style="white-space:pre">         </span>struct ast_stream *existing_stream = NULL;</div><div><span style="white-space:pre">            </span>struct ast_stream *stream;</div><div><span style="white-space:pre">            </span>enum ast_media_type type;</div><div><span style="white-space:pre">             </span>struct ast_sip_session_media *session_media = NULL;</div><div><span style="white-space:pre">           </span>enum ast_sip_session_sdp_stream_defer res;</div><div><br></div><div><span style="white-space:pre">           </span>/* We need a null-terminated version of the media string */</div><div><span style="white-space:pre">           </span>ast_copy_pj_str(media, &sdp->media[i]->desc.media, sizeof(media));</div><div><br></div><div>              <span style="background-color:rgb(255,255,255)">  <font color="#ff0000">/* The stream count of B's active_media_state->topology is 3, one B's audio, one B's video, one A's video with name softbridge_dest_PJSIP... </font></span></div><div><span style="background-color:rgb(255,255,255)"><font color="#ff0000">                   The sdp->media_count is 3, one for audio, one for camera video, one for sharing video</font></span></div><div><span style="background-color:rgb(255,255,255)"><font color="#ff0000">                   Here B's sharing video is map to A's video with name softbridge_dest_PJSIP...  */</font></span></div><div><span style="white-space:pre">               </span>if (session->active_media_state->topology &&</div><div><span style="white-space:pre">                    </span>(i < ast_stream_topology_get_count(session->active_media_state->topology))) {</div><div><span style="white-space:pre">                        </span>existing_stream = ast_stream_topology_get_stream(session->active_media_state->topology, i);</div><div><span style="white-space:pre">             </span>}</div><div><br></div><div><span style="white-space:pre">            </span>type = ast_media_type_from_str(media);</div><div><span style="white-space:pre">                </span>stream = ast_stream_alloc(existing_stream ? ast_stream_get_name(existing_stream) : ast_codec_media_type2str(type), type);</div><div><span style="white-space:pre">             </span>if (!stream) {</div><div><span style="white-space:pre">                        </span>return -1;</div><div><span style="white-space:pre">            </span>}</div><div><br></div><div><span style="white-space:pre">            </span>/* As this is only called on an incoming SDP offer before processing it is not possible</div><div><span style="white-space:pre">               </span> * for streams and their media sessions to exist.</div><div><span style="white-space:pre">             </span> */</div><div><span style="white-space:pre">           </span>if (ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream)) {</div><div><span style="white-space:pre">                        </span>ast_stream_free(stream);</div><div><span style="white-space:pre">                      </span>return -1;</div><div><span style="white-space:pre">            </span>}</div><div><br></div><div><span style="white-space:pre">            </span>session_media = ast_sip_session_media_state_add(session, session->pending_media_state, ast_media_type_from_str(media), i);</div><div><span style="white-space:pre">         </span>if (!session_media) {</div><div><span style="white-space:pre">                 </span>return -1;</div><div><span style="white-space:pre">            </span>}</div><div><br></div><div>               <font color="#ff0000">/* If the code of B's new sharing video stream executes here, does it need to call set_mid_and_bundle_group() & set_remote_mslabel_and_stream_group() </font></div><div><font color="#ff0000">                  &  handler->negotiate_incoming_sdp_stream for the new stream setup instead of the handler->defer_incoming_sdp_stream()?</font></div><div><font color="#ff0000">               */</font></div><div><br></div><div><span style="white-space:pre">              </span>if (session_media->handler) {</div><div><span style="white-space:pre">                      </span>handler = session_media->handler;</div><div><span style="white-space:pre">                  </span>if (handler->defer_incoming_sdp_stream) {</div><div><span style="white-space:pre">                          </span>res = handler->defer_incoming_sdp_stream(session, session_media, sdp,</div><div><span style="white-space:pre">                                      </span>sdp->media[i]);</div><div><span style="white-space:pre">                            </span>switch (res) {</div><div><span style="white-space:pre">                                </span>case AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED:</div><div><span style="white-space:pre">                                   </span>break;</div><div><span style="white-space:pre">                                </span>case AST_SIP_SESSION_SDP_DEFER_ERROR:</div><div><span style="white-space:pre">                                 </span>return 0;</div><div><span style="white-space:pre">                             </span>case AST_SIP_SESSION_SDP_DEFER_NOT_NEEDED:</div><div><span style="white-space:pre">                                    </span>break;</div><div><span style="white-space:pre">                                </span>case AST_SIP_SESSION_SDP_DEFER_NEEDED:</div><div><span style="white-space:pre">                                        </span>return 1;</div><div><span style="white-space:pre">                             </span>}</div><div><span style="white-space:pre">                     </span>}</div><div><span style="white-space:pre">                     </span>/* Handled by this handler. Move to the next stream */</div><div><span style="white-space:pre">                        </span>continue;</div><div><span style="white-space:pre">             </span>}</div><div><br></div><div><span style="white-space:pre">            </span>handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);</div><div><span style="white-space:pre">                </span>if (!handler_list) {</div><div><span style="white-space:pre">                  </span>ast_debug(1, "No registered SDP handlers for media type '%s'\n", media);</div><div><span style="white-space:pre">                    </span>continue;</div><div><span style="white-space:pre">             </span>}</div><div><span style="white-space:pre">             </span>AST_LIST_TRAVERSE(&handler_list->list, handler, next) {</div><div><span style="white-space:pre">                        </span>if (handler == session_media->handler) {</div><div><span style="white-space:pre">                           </span>continue;</div><div><span style="white-space:pre">                     </span>}</div><div><span style="white-space:pre">                     </span>if (!handler->defer_incoming_sdp_stream) {</div><div><span style="white-space:pre">                         </span>continue;</div><div><span style="white-space:pre">                     </span>}</div><div><span style="white-space:pre">                     </span>res = handler->defer_incoming_sdp_stream(session, session_media, sdp,</div><div><span style="white-space:pre">                              </span>sdp->media[i]);</div><div><span style="white-space:pre">                    </span>switch (res) {</div><div><span style="white-space:pre">                        </span>case AST_SIP_SESSION_SDP_DEFER_NOT_HANDLED:</div><div><span style="white-space:pre">                           </span>continue;</div><div><span style="white-space:pre">                     </span>case AST_SIP_SESSION_SDP_DEFER_ERROR:</div><div><span style="white-space:pre">                         </span>session_media_set_handler(session_media, handler);</div><div><span style="white-space:pre">                            </span>return 0;</div><div><span style="white-space:pre">                     </span>case AST_SIP_SESSION_SDP_DEFER_NOT_NEEDED:</div><div><span style="white-space:pre">                            </span>/* Handled by this handler. */</div><div><span style="white-space:pre">                                </span>session_media_set_handler(session_media, handler);</div><div><span style="white-space:pre">                            </span>break;</div><div><span style="white-space:pre">                        </span>case AST_SIP_SESSION_SDP_DEFER_NEEDED:</div><div><span style="white-space:pre">                                </span>/* Handled by this handler. */</div><div><span style="white-space:pre">                                </span>session_media_set_handler(session_media, handler);</div><div><span style="white-space:pre">                            </span>return 1;</div><div><span style="white-space:pre">                     </span>}</div><div><span style="white-space:pre">                     </span>/* Move to the next stream */</div><div><span style="white-space:pre">                 </span>break;</div><div><span style="white-space:pre">                </span>}</div><div><span style="white-space:pre">     </span>}</div><div><span style="white-space:pre">     </span>return 0;</div><div>}</div><div><br></div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Joshua C. Colp <<a href="mailto:jcolp@digium.com">jcolp@digium.com</a>> 于2019年5月8日周三 下午5:14写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, May 8, 2019, at 12:07 AM, Xiemin Chen wrote:<br>
> Hi there,<br>
> <br>
> *Problem*<br>
> <br>
> In a WebRTC conference, participant A & B join with only one video <br>
> track, then B add another video track with the SDP renegotiate, A <br>
> cannot see B's two video tracks.<br>
> <br>
> *Root Cause*<br>
> *<br>
> *<br>
> After work through the source code, the problem may caused by the <br>
> sdp_requires_deferral() in res_pjsip_session.c:<br>
> It does not take of the situation of the new creation of the video <br>
> track.<br>
> <br>
> *Solution*<br>
> <br>
> Can I use the handle_incoming_sdp() to replace the <br>
> sdp_requires_deferal() ? handle_incoming_sdp() function is called <br>
> during the init of the session, it does the track initial progress.<br>
<br>
The sdp_requires_deferral function and its functionality has to continue to exist, or T.38 fax will be non-functional. The sdp_requires_deferral function would need to be examined based on your scenario and adjusted accordingly however it makes sense. Looking at the function I'm also not sure why it would cause any problems with your scenario, as it should just result in some things being set up and that's pretty much it but I have not looked into it deeply or reproduced the problem.<br>
<br>
-- <br>
Joshua C. Colp<br>
Digium - A Sangoma Company | Senior Software Developer<br>
445 Jan Davis Drive NW - Huntsville, AL 35806 - US<br>
Check us out at: <a href="http://www.digium.com" rel="noreferrer" target="_blank">www.digium.com</a> & <a href="http://www.asterisk.org" rel="noreferrer" target="_blank">www.asterisk.org</a><br>
<br>
-- <br>
_____________________________________________________________________<br>
-- Bandwidth and Colocation Provided by <a href="http://www.api-digital.com" rel="noreferrer" target="_blank">http://www.api-digital.com</a> --<br>
<br>
asterisk-dev mailing list<br>
To UNSUBSCRIBE or update options visit:<br>
   <a href="http://lists.digium.com/mailman/listinfo/asterisk-dev" rel="noreferrer" target="_blank">http://lists.digium.com/mailman/listinfo/asterisk-dev</a></blockquote></div>