mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-06 21:33:08 +00:00
- rewrite mirroring
- fix bug with handling of remote RTP address while generating SDP answer - fix H264 packetization-mode handling in SDP answer git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@54 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
parent
e11af61545
commit
52c3634a4f
7 changed files with 89 additions and 154 deletions
|
|
@ -490,14 +490,14 @@ static int find_payload_type_number_best_match(RtpProfile *prof, const char *rtp
|
|||
pt=rtp_profile_get_payload(prof,localpt);
|
||||
if (strcasecmp(pt->mime_type,"H264")==0){
|
||||
/*hack for H264: need to answer with same packetization-mode*/
|
||||
PayloadType tmp;
|
||||
memset(&tmp,0,sizeof(tmp));
|
||||
tmp.mime_type="H264";
|
||||
tmp.clock_rate=pt->clock_rate;
|
||||
if (fmtp && fmtp_get_value(fmtp,"packetization-mode",value,sizeof(value))){
|
||||
PayloadType tmp;
|
||||
memset(&tmp,0,sizeof(tmp));
|
||||
tmp.mime_type="H264";
|
||||
tmp.clock_rate=pt->clock_rate;
|
||||
tmp.recv_fmtp=(atoi(value)==1) ? "packetization-mode=1" : NULL;
|
||||
localpt=find_payload_type_number(prof,&tmp);
|
||||
}
|
||||
localpt=find_payload_type_number(prof,&tmp);
|
||||
}
|
||||
return localpt;
|
||||
}
|
||||
|
|
@ -643,12 +643,12 @@ int linphone_accept_audio_offer(sdp_context_t *ctx,sdp_payload_t *payload)
|
|||
params->line=payload->line;
|
||||
params->pt=payload->pt; /* remember the first payload accepted */
|
||||
if (payload->relay_host!=NULL){
|
||||
params->remoteaddr=payload->relay_host;
|
||||
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->relay_port;
|
||||
params->remotertcpport=payload->relay_port;
|
||||
params->relay_session_id=payload->relay_session_id;
|
||||
}else{
|
||||
params->remoteaddr=payload->c_addr;
|
||||
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->remoteport;
|
||||
params->remotertcpport=payload->remoteport+1;
|
||||
}
|
||||
|
|
@ -694,12 +694,12 @@ int linphone_accept_video_offer(sdp_context_t *ctx,sdp_payload_t *payload)
|
|||
params->line=payload->line;
|
||||
params->pt=payload->pt; /* remember the first payload accepted */
|
||||
if (payload->relay_host!=NULL){
|
||||
params->remoteaddr=payload->relay_host;
|
||||
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->relay_port;
|
||||
params->remotertcpport=payload->relay_port;
|
||||
params->relay_session_id=payload->relay_session_id;
|
||||
}else{
|
||||
params->remoteaddr=payload->c_addr;
|
||||
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->remoteport;
|
||||
params->remotertcpport=params->remoteport+1;
|
||||
}
|
||||
|
|
@ -735,12 +735,12 @@ int linphone_read_audio_answer(sdp_context_t *ctx,sdp_payload_t *payload)
|
|||
params->line=payload->line;
|
||||
params->pt=payload->pt; /* remember the first payload accepted */
|
||||
if (payload->relay_host!=NULL){
|
||||
params->remoteaddr=payload->relay_host;
|
||||
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->relay_port;
|
||||
params->remotertcpport=payload->relay_port;
|
||||
params->relay_session_id=payload->relay_session_id;
|
||||
}else{
|
||||
params->remoteaddr=payload->c_addr;
|
||||
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->remoteport;
|
||||
params->remotertcpport=payload->remoteport+1;
|
||||
}
|
||||
|
|
@ -774,12 +774,12 @@ int linphone_read_video_answer(sdp_context_t *ctx,sdp_payload_t *payload)
|
|||
params->line=payload->line;
|
||||
params->pt=payload->pt; /* remember the first payload accepted */
|
||||
if (payload->relay_host!=NULL){
|
||||
params->remoteaddr=payload->relay_host;
|
||||
strncpy(params->remoteaddr,payload->relay_host,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->relay_port;
|
||||
params->remotertcpport=payload->relay_port;
|
||||
params->relay_session_id=payload->relay_session_id;
|
||||
}else{
|
||||
params->remoteaddr=payload->c_addr;
|
||||
strncpy(params->remoteaddr,payload->c_addr,sizeof(params->remoteaddr)-1);
|
||||
params->remoteport=payload->remoteport;
|
||||
params->remotertcpport=payload->remoteport+1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1506,18 +1506,13 @@ int linphone_core_accept_call(LinphoneCore *lc, const char *url)
|
|||
ms_error("fail to generate sdp offer !");
|
||||
return -1;
|
||||
}
|
||||
ms_message("sdp message generated (sdpmesg=%p):\n%s",sdpmesg,sdpmesg);
|
||||
linphone_set_sdp(msg,sdpmesg);
|
||||
ms_message("sdp message attached to SIP answer");
|
||||
linphone_core_init_media_streams(lc);
|
||||
ms_message("init_media_streams done");
|
||||
}else{
|
||||
linphone_set_sdp(msg,sdpmesg);
|
||||
}
|
||||
eXosip_lock();
|
||||
ms_message("eXosip_lock() done");
|
||||
eXosip_call_send_answer(call->tid,200,msg);
|
||||
ms_message("SIP answer sent.");
|
||||
eXosip_unlock();
|
||||
lc->vtable.display_status(lc,_("Connected."));
|
||||
gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "mediastreamer2/mscommon.h"
|
||||
|
||||
#define LINPHONE_IPADDR_SIZE 64
|
||||
#define LINPHONE_HOSTNAME_SIZE 128
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -144,11 +145,11 @@ typedef struct _StreamParams
|
|||
int localport;
|
||||
int remoteport;
|
||||
int remotertcpport;
|
||||
char *remoteaddr;
|
||||
int pt;
|
||||
char *relay_session_id;
|
||||
char natd_addr[LINPHONE_IPADDR_SIZE];
|
||||
int natd_port;
|
||||
char remoteaddr[LINPHONE_HOSTNAME_SIZE];
|
||||
char natd_addr[LINPHONE_HOSTNAME_SIZE];
|
||||
} StreamParams;
|
||||
|
||||
typedef enum _LCState{
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ void yuv_buf_init_from_mblk_with_size(MSPicture *buf, mblk_t *m, int w, int h);
|
|||
mblk_t * yuv_buf_alloc(MSPicture *buf, int w, int h);
|
||||
void yuv_buf_copy(uint8_t *src_planes[], const int src_strides[],
|
||||
uint8_t *dst_planes[], const int dst_strides[3], MSVideoSize roi);
|
||||
void yuv_buf_mirror(YuvBuf *buf);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -174,11 +174,11 @@ static int enc_set_br(MSFilter *f, void *arg){
|
|||
d->bitrate=*(int*)arg;
|
||||
|
||||
if (d->bitrate>=1024000){
|
||||
d->vsize=MS_VIDEO_SIZE_VGA;
|
||||
d->fps=15;
|
||||
d->vsize=MS_VIDEO_SIZE_VGA;
|
||||
d->fps=15;
|
||||
}else if (d->bitrate>=384000){
|
||||
d->vsize=MS_VIDEO_SIZE_CIF;
|
||||
d->fps=30;
|
||||
d->vsize=MS_VIDEO_SIZE_CIF;
|
||||
d->fps=30;
|
||||
}else if (d->bitrate>=256000){
|
||||
d->vsize=MS_VIDEO_SIZE_CIF;
|
||||
d->fps=15;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,26 @@ void yuv_buf_copy(uint8_t *src_planes[], const int src_strides[],
|
|||
plane_copy(src_planes[2],src_strides[2],dst_planes[2],dst_strides[2],roi);
|
||||
}
|
||||
|
||||
static void plane_mirror(uint8_t *p, int linesize, int w, int h){
|
||||
int i,j;
|
||||
uint8_t tmp;
|
||||
for(j=0;j<h;++j){
|
||||
for(i=0;i<w/2;++i){
|
||||
tmp=p[i];
|
||||
p[i]=p[w-1-i];
|
||||
p[w-1-i]=tmp;
|
||||
}
|
||||
p+=linesize;
|
||||
}
|
||||
}
|
||||
|
||||
/*in place mirroring*/
|
||||
void yuv_buf_mirror(YuvBuf *buf){
|
||||
plane_mirror(buf->planes[0],buf->strides[0],buf->w,buf->h);
|
||||
plane_mirror(buf->planes[1],buf->strides[1],buf->w/2,buf->h/2);
|
||||
plane_mirror(buf->planes[2],buf->strides[2],buf->w/2,buf->h/2);
|
||||
}
|
||||
|
||||
#ifndef MAKEFOURCC
|
||||
#define MAKEFOURCC(a,b,c,d) ((d)<<24 | (c)<<16 | (b)<<8 | (a))
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -521,9 +521,6 @@ typedef struct VideoOut
|
|||
MSPicture local_pic;
|
||||
MSRect local_rect;
|
||||
mblk_t *local_msg;
|
||||
MSPicture tmp_local_pic;
|
||||
mblk_t *tmp_local_msg;
|
||||
mblk_t *previous_selfview;
|
||||
int corner;
|
||||
struct SwsContext *sws1;
|
||||
struct SwsContext *sws2;
|
||||
|
|
@ -537,44 +534,42 @@ typedef struct VideoOut
|
|||
|
||||
static void set_corner(VideoOut *s, int corner)
|
||||
{
|
||||
s->corner=corner;
|
||||
s->local_pic.w=s->fbuf.w/SCALE_FACTOR;
|
||||
s->local_pic.h=s->fbuf.h/SCALE_FACTOR;
|
||||
s->tmp_local_pic.h = s->local_pic.h;
|
||||
s->tmp_local_pic.w = s->local_pic.w;
|
||||
if (corner==1)
|
||||
{
|
||||
/* top left corner */
|
||||
s->corner=corner;
|
||||
s->local_pic.w=s->fbuf.w/SCALE_FACTOR;
|
||||
s->local_pic.h=s->fbuf.h/SCALE_FACTOR;
|
||||
if (corner==1)
|
||||
{
|
||||
/* top left corner */
|
||||
s->local_rect.x=0;
|
||||
s->local_rect.y=0;
|
||||
s->local_rect.w=s->local_pic.w;
|
||||
s->local_rect.h=s->local_pic.h;
|
||||
}
|
||||
else if (corner==2)
|
||||
{
|
||||
/* top right corner */
|
||||
}
|
||||
else if (corner==2)
|
||||
{
|
||||
/* top right corner */
|
||||
s->local_rect.x=s->fbuf.w-s->local_pic.w;
|
||||
s->local_rect.y=0;
|
||||
s->local_rect.w=s->local_pic.w;
|
||||
s->local_rect.h=s->local_pic.h;
|
||||
}
|
||||
else if (corner==3)
|
||||
{
|
||||
/* bottom left corner */
|
||||
}
|
||||
else if (corner==3)
|
||||
{
|
||||
/* bottom left corner */
|
||||
s->local_rect.x=0;
|
||||
s->local_rect.y=s->fbuf.h-s->local_pic.h;
|
||||
s->local_rect.w=s->local_pic.w;
|
||||
s->local_rect.h=s->local_pic.h;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default: bottom right corner */
|
||||
/* corner can be set to -1: to disable the self view... */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default: bottom right corner */
|
||||
/* corner can be set to -1: to disable the self view... */
|
||||
s->local_rect.x=s->fbuf.w-s->local_pic.w;
|
||||
s->local_rect.y=s->fbuf.h-s->local_pic.h;
|
||||
s->local_rect.w=s->local_pic.w;
|
||||
s->local_rect.h=s->local_pic.h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_vsize(VideoOut *s, MSVideoSize *sz){
|
||||
|
|
@ -595,8 +590,6 @@ static void video_out_init(MSFilter *f){
|
|||
def_size.width=MS_VIDEO_SIZE_CIF_W;
|
||||
def_size.height=MS_VIDEO_SIZE_CIF_H;
|
||||
obj->local_msg=NULL;
|
||||
obj->tmp_local_msg=NULL;
|
||||
obj->previous_selfview=NULL;
|
||||
obj->corner=0;
|
||||
obj->sws1=NULL;
|
||||
obj->sws2=NULL;
|
||||
|
|
@ -624,15 +617,6 @@ static void video_out_uninit(MSFilter *f){
|
|||
freemsg(obj->local_msg);
|
||||
obj->local_msg=NULL;
|
||||
}
|
||||
if (obj->previous_selfview!=NULL)
|
||||
{
|
||||
freemsg(obj->previous_selfview);
|
||||
obj->previous_selfview=NULL;
|
||||
}
|
||||
if (obj->tmp_local_msg!=NULL) {
|
||||
freemsg(obj->tmp_local_msg);
|
||||
obj->tmp_local_msg=NULL;
|
||||
}
|
||||
ms_free(obj);
|
||||
}
|
||||
|
||||
|
|
@ -663,32 +647,12 @@ static void video_out_preprocess(MSFilter *f){
|
|||
freemsg(obj->local_msg);
|
||||
obj->local_msg=NULL;
|
||||
}
|
||||
if (obj->previous_selfview!=NULL)
|
||||
{
|
||||
freemsg(obj->previous_selfview);
|
||||
obj->previous_selfview=NULL;
|
||||
}
|
||||
if (obj->tmp_local_msg!=NULL) {
|
||||
freemsg(obj->tmp_local_msg);
|
||||
obj->tmp_local_msg=NULL;
|
||||
}
|
||||
obj->ready=TRUE;
|
||||
}
|
||||
|
||||
static void video_out_postprocess(MSFilter *f){
|
||||
}
|
||||
|
||||
static void mirror(unsigned char* dst,unsigned char* src,int dststride,int srcstride,int w,int h){
|
||||
int y;
|
||||
for(y=0;y<h;y++){
|
||||
int x;
|
||||
for(x=0;x<w;x++)
|
||||
dst[x]=src[w-x-1];
|
||||
src+=srcstride;
|
||||
dst+=dststride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void video_out_process(MSFilter *f){
|
||||
VideoOut *obj=(VideoOut*)f->data;
|
||||
|
|
@ -702,85 +666,39 @@ static void video_out_process(MSFilter *f){
|
|||
if (obj->display==NULL){
|
||||
ms_filter_unlock(f);
|
||||
if (f->inputs[0]!=NULL)
|
||||
ms_queue_flush(f->inputs[0]);
|
||||
ms_queue_flush(f->inputs[0]);
|
||||
if (f->inputs[1]!=NULL)
|
||||
ms_queue_flush(f->inputs[1]);
|
||||
ms_queue_flush(f->inputs[1]);
|
||||
return;
|
||||
}
|
||||
/*get most recent message and draw it*/
|
||||
if (f->inputs[1]!=NULL && (inm=ms_queue_peek_last(f->inputs[1]))!=0) {
|
||||
|
||||
if (obj->corner==-1)
|
||||
{
|
||||
if (obj->tmp_local_msg!=NULL) {
|
||||
freemsg(obj->tmp_local_msg);
|
||||
obj->tmp_local_msg=NULL;
|
||||
}
|
||||
if (obj->local_msg!=NULL) {
|
||||
freemsg(obj->local_msg);
|
||||
obj->local_msg=NULL;
|
||||
}
|
||||
if (obj->previous_selfview!=NULL)
|
||||
{
|
||||
freemsg(obj->previous_selfview);
|
||||
obj->previous_selfview=NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MSPicture src;
|
||||
static mblk_t *previous_selfview = NULL;
|
||||
if (yuv_buf_init_from_mblk(&src,inm)==0){
|
||||
|
||||
if (obj->sws2==NULL){
|
||||
obj->sws2=sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
|
||||
obj->local_pic.w,obj->local_pic.h,PIX_FMT_YUV420P,
|
||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||
}
|
||||
obj->tmp_local_pic.h = obj->local_pic.h;
|
||||
obj->tmp_local_pic.w = obj->local_pic.w;
|
||||
if (obj->tmp_local_msg==NULL){
|
||||
obj->tmp_local_msg=yuv_buf_alloc(&obj->tmp_local_pic,
|
||||
obj->tmp_local_pic.w,obj->tmp_local_pic.h);
|
||||
}
|
||||
if (obj->local_msg==NULL){
|
||||
obj->local_msg=yuv_buf_alloc(&obj->local_pic,
|
||||
obj->local_pic.w,obj->local_pic.h);
|
||||
}
|
||||
|
||||
if (previous_selfview==NULL
|
||||
|| (msgdsize(inm)!=msgdsize(previous_selfview))
|
||||
|| memcmp(inm->b_rptr, previous_selfview->b_rptr, msgdsize(inm))!=0)
|
||||
{
|
||||
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
|
||||
src.h, obj->tmp_local_pic.planes, obj->tmp_local_pic.strides)<0){
|
||||
ms_error("Error in sws_scale().");
|
||||
}
|
||||
|
||||
mirror(obj->local_pic.planes[0],obj->tmp_local_pic.planes[0],
|
||||
obj->local_pic.strides[0],obj->tmp_local_pic.strides[0],
|
||||
obj->local_pic.w,obj->local_pic.h);
|
||||
mirror(obj->local_pic.planes[1],obj->tmp_local_pic.planes[1],
|
||||
obj->local_pic.strides[1],obj->tmp_local_pic.strides[1],
|
||||
obj->local_pic.w>>1,obj->local_pic.h>>1);
|
||||
mirror(obj->local_pic.planes[2],obj->tmp_local_pic.planes[2],
|
||||
obj->local_pic.strides[2],obj->tmp_local_pic.strides[2],
|
||||
obj->local_pic.w>>1,obj->local_pic.h>>1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
|
||||
src.h, obj->local_pic.planes, obj->local_pic.strides)<0){
|
||||
ms_error("Error in sws_scale().");
|
||||
}
|
||||
}
|
||||
|
||||
if (previous_selfview!=NULL)
|
||||
freemsg(previous_selfview);
|
||||
previous_selfview = dupb(inm);
|
||||
}
|
||||
}
|
||||
ms_queue_flush(f->inputs[1]);
|
||||
if (obj->corner==-1){
|
||||
if (obj->local_msg!=NULL) {
|
||||
freemsg(obj->local_msg);
|
||||
obj->local_msg=NULL;
|
||||
}
|
||||
}else{
|
||||
MSPicture src;
|
||||
if (yuv_buf_init_from_mblk(&src,inm)==0){
|
||||
|
||||
if (obj->sws2==NULL){
|
||||
obj->sws2=sws_getContext(src.w,src.h,PIX_FMT_YUV420P,
|
||||
obj->local_pic.w,obj->local_pic.h,PIX_FMT_YUV420P,
|
||||
SWS_FAST_BILINEAR, NULL, NULL, NULL);
|
||||
}
|
||||
if (obj->local_msg==NULL){
|
||||
obj->local_msg=yuv_buf_alloc(&obj->local_pic,
|
||||
obj->local_pic.w,obj->local_pic.h);
|
||||
}
|
||||
if (sws_scale(obj->sws2,src.planes,src.strides, 0,
|
||||
src.h, obj->local_pic.planes, obj->local_pic.strides)<0){
|
||||
ms_error("Error in sws_scale().");
|
||||
}
|
||||
yuv_buf_mirror(&obj->local_pic);
|
||||
}
|
||||
}
|
||||
ms_queue_flush(f->inputs[1]);
|
||||
}
|
||||
|
||||
if (f->inputs[0]!=NULL && (inm=ms_queue_peek_last(f->inputs[0]))!=0) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue